read-r 대 read-r 라인 및 IFS

read-r 대 read-r 라인 및 IFS

나는 IFS 관련 내용을 만지작거렸지만 다양한 코드 조각의 동작을 설명할 수 없습니다. 요약하면 다음과 같습니다.

$ read -r < <(printf "%s\n" " x ")  && echo \<"$REPLY"\>
< x >
$ read -r line < <(printf "%s\n" " x ")  && echo \<"$line"\>
<x>

물론 man bash우리는 필요한 모든 것을 갖추고 있습니다.

이름이 제공되지 않은 경우,읽은 줄은 REPLY 변수에 할당됩니다.. 파일 끝이 발생하거나, 읽기 시간 초과가 발생하거나(이 경우 반환 코드가 128보다 큰 경우), 변수 할당 오류가 발생하거나(예: 읽기 전용 변수에 할당) 잘못된 파일이 아닌 한 반환 코드는 0입니다. 설명자는 -u에 대한 인수로 제공됩니다.

IFS 관련 답변 중 하나에 이에 대한 문장이 포함되어 있으면 좋을 것이라고 생각했습니다.이유. 일부는 공개적으로 틀린 것으로 드러났습니다. 예는 이 단락의 편집입니다.이 답변:

읽기는 IFS가 매개변수와 함께 호출되지 않는 한 IFS를 사용하지 않습니다. (편집하다: 이것은 완전히 정확하지 않습니다. IFS에 있는 공백 문자(예: 공백 및 탭)는 입력 줄의 시작/끝에서 항상 무시됩니다. )

물음표가 없는 수사적 질문입니다. 하지만 내가 틀렸다면 정정해 주세요.

답변1

모든 Bourne/POSIX 셸(dash, ksh, pdksh, mksh, bash, zsh, sh 에뮬레이션 모드가 아닌 경우에도 BusyBox sh, Bourne 셸 등)에서 뒤따르는 일반적인 동작은 read -r line앞뒤 공백 문자를 제거하는 것입니다. 보다 일반적으로, read -r line공백 문자로 구성된 선행 구분 기호는 공백 문자에서 제거되고, IFS공백이 아닌 문자는 최대 한 개만 제거됩니다 IFS. 줄 끝에서는 공백 문자만 제거할 수 있습니다. 왜냐하면 줄이 공백이 아닌 구분 기호로 끝나면 빈 필드로 끝나기 때문입니다. 이는 보다 일반적인 경우의 특수한 경우입니다. 첫 번째 변수는 첫 번째 필드를 가져오고, 두 번째 변수는 두 번째 필드를 가져오는 식으로, 변수보다 필드가 더 많은 경우 마지막 변수는 행의 나머지 부분을 가져옵니다. 후행 공백.

암시적 변수 이름을 사용한 호출은 readbash 및 zsh에서 에뮬레이트된 ksh 확장입니다. ksh(ATT 및 pdksh/mksh) 및 zsh에서는 변수 read이름이 있는 것과 정확히 동일한 변수 이름이 없습니다. Bash에서는 어떤 이유로 동작이 다릅니다. 즉, 변수 이름이 암시적일 때 공백 제거가 수행되지 않습니다. 의도적인데 다르게 하는 이유를 모르겠습니다. (스트리핑을 원하지 않는 경우 표준 접근 방식은 실행하는 것입니다.)readREPLYIFSIFS= read -r

  /* If there are no variables, save the text of the line read to the
     variable $REPLY.  ksh93 strips leading and trailing IFS whitespace,
     so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
     same way, but I believe that the difference in behaviors is useful
     enough to not do it.  Without the bash behavior, there is no way
     to read a line completely without interpretation or modification
     unless you mess with $IFS (e.g., setting it to the empty string).
     If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
  if (list == 0)
    {
#if 0
      orig_input_string = input_string;
      for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t
        ;
      input_string = t;
      input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw
#endif

관련 정보