対話形式でファイルをコピーする: "cp:overwrite"

対話形式でファイルをコピーする:

-i対話型オプションがcp入力として受け入れる単語を見つけようとします。

便宜上、実験に使用するファイルを設定するコードは以下のとおりです。

touch example_file{1..3}
mkdir example_dir
cp example_file? example_dir
cp -i example_file? example_dir

その後、シェルは各ファイルを上書きする必要があるかどうかを対話的に尋ねます。いろいろなランダムな入力に対応しているようです。

cp: overwrite 'example_dir/example_file1'? q
cp: overwrite 'example_dir/example_file2'? w
cp: overwrite 'example_dir/example_file3'? e

私は調査しようとしていますソースコードcpしかし、Cを理解していないので検索してもoverwrite役に立ちませんでした。

私が知っている限り、一部の単語は保証確認として受け入れられ、残りはすべて拒否として扱われます。問題は、このような言葉でさえそのようにys受け入れられているようで、yes何がうまくいくのか、何がうまくいかないのかわからないということです。

正確にどのように動作するかを知りたい、文書や方法で証明したいです。理解できるソースコードの断片。

ベストアンサー1

POSIX規格-iレプリケーションを適用するには、応答が「肯定的」でなければならないことを指定します。

GNUの場合、cpこの時点の実際の入力はという関数によって処理されますyesno()。この関数は以下で定義されます。lib/yesno.c以下のようにgnulibソースディストリビューション:

bool
yesno (void)
{
  bool yes;

#if ENABLE_NLS
  char *response = NULL;
  size_t response_size = 0;
  ssize_t response_len = getline (&response, &response_size, stdin);

  if (response_len <= 0)
    yes = false;
  else
    {
      /* Remove EOL if present as that's not part of the matched response,
         and not matched by $ for example.  */
      if (response[response_len - 1] == '\n')
        response[response_len - 1] = '\0';
      yes = (0 < rpmatch (response));
    }

  free (response);
#else
  /* Test against "^[yY]", hardcoded to avoid requiring getline,
     regex, and rpmatch.  */
  int c = getchar ();
  yes = (c == 'y' || c == 'Y');
  while (c != '\n' && c != EOF)
    c = getchar ();
#endif

  return yes;
}

NLS(「国別言語サポート」)いいえ以下を使用した後、関数から返された唯一の応答を見ることができます。本物forは大文字または小文字で始まる応答ですY。追加入力やその他の入力は削除されます。

NLSの場合はい使用時にこのrpmatch()関数を呼び出して、応答が肯定的であることを確認してください。 NLSライブラリ関数の目的は、rpmatch()与えられた文字列が正であるか(国際化サポート)かどうかを確認することです。

BSDシステムでは、その機能は次の場所にあります。src/bin/cp/utils.c:

/*
 * If the file exists and we're interactive, verify with the user.
 */
int
copy_overwrite(void)
{
        int ch, checkch;

        if (iflag) {
                (void)fprintf(stderr, "overwrite %s? ", to.p_path);
                checkch = ch = getchar();
                while (ch != '\n' && ch != EOF)
                        ch = getchar();
                if (checkch != 'y' && checkch != 'Y')
                        return (0);
        }
        return 1;
}

これは、基本的にGNUコードのNLS以外のコードパスと同じです。

おすすめ記事