대화형으로 파일 복사: "cp:overwrite"

대화형으로 파일 복사: "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가 아닌 코드 경로와 동일합니다.

답변2

소스코드를 보고 검색해 보면 interactive설정되어 있는 것을 볼 수 있으니 이 파일과 체크되어 있는 x.interactive = I_ASK_USER;다른 파일에서도 검색이 가능합니다 .I_ASK_USER

copy.c이 기호는 함수 호출 근처에서 찾을 수 overwrite_ok있으며 이 함수에는 함수에 대한 호출이 포함되어 있습니다 yesno.

나머지는 독자의 연습문제로 남겨둔다. ;-)

관련 정보