-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以外のコードパスと同じです。
答え2
ソースコードを見て検索してみるとinteractive
設定されていることがわかりますので、このファイルとチェックされているx.interactive = I_ASK_USER;
他のファイルでも検索が可能です。I_ASK_USER
copy.c
このシンボルは関数呼び出しの近くにあり、関数overwrite_ok
には関数呼び出しが含まれていますyesno
。
残りは読者の練習問題として残しておく。 ;-)