IFS를 null로 설정하면 선행 공백 시퀀스가 ​​무시되지 않습니다.

IFS를 null로 설정하면 선행 공백 시퀀스가 ​​무시되지 않습니다.

매뉴얼에 따르면:

If IFS is unset, or its value
       is exactly <space><tab><newline>, the default, then sequences of
       <space>, <tab>, and <newline> at the beginning and end of the
       results of the previous expansions are ignored, and any sequence
       of IFS characters not at the beginning or end serves to delimit
       words.

그리고:

If
       the value of IFS is null, no word splitting occurs.

여기서 얻은 것은 IFS가 비어 있으면 토큰화가 발생하지 않으므로 일련의 선행 공백, 탭 및 줄 바꿈이 무시되지 않는다는 것입니다.

이 진술이 정확하다면 왜 공백 문자 대신 IFS= echo sssssssssssssssXYZ인쇄합니까 ?XYZsssssssssssssssXYZs

매개변수 확장, 명령어 확장, 산술 확장 결과에만 영향을 미치기 때문일까요?

그렇다면 왜 선행 공백 문자를 에코 인쇄하지 않습니까?

답변1

많은 이유.

첫째, 토큰화는 IFS명령줄(*)의 텍스트에 직접 적용되지 않고 확장된 결과에만 적용됩니다. 명령줄을 단어로 나누는 것은 다르며, 따옴표가 없는 연속 공백은 거기에 있는 공백과 동일합니다. 에서는 하나의 매개변수 somecmd foo:barsomecmd가져오는 반면 에서는 콜론 또는 공백 포함 somecmd foo bar여부에 관계없이 IFS두 개의 매개변수를 가져옵니다 . 에서는 단일 매개변수를 가져 echo xyz옵니다 .echoxyz

둘째, IFS명령줄에서 구문 분석을 시작하기 전에 설정한 값이 중요합니다. 설정 var=foo:bar하고 실행 하면 여전히 다음을 얻습니다 IFS=: printf "%s\n" $var.printf하나형식 문자열을 따르고 foo:bar한 줄에 출력되는 매개변수입니다. 동일한 명령의 변수 설정은 해당 명령 내에서만 적용됩니다.~에그것을 사용하거나 사용 printf하지 않습니다 .echoIFS

이를 적용하려면 이전 명령을 설정해야 합니다 IFS. 예를 들어 이렇게 하면 두 개의 개별 라인에 합계가 인쇄됩니다 foo. 이렇게 하면 공백이 보존됩니다: .barvar=foo:bar IFS=:; printf "%s\n" $varvar=" foo" IFS=:; printf "%s\n" $var

그러나 대부분의 경우 확장명을 인용하는 것이 더 좋습니다. 이렇게 하면 토큰화로부터 결과가 보호됩니다.그리고값에 관계없이 와일드카드입니다 IFS.

(*AFAIK 일부 ​​초기 쉘에서는 IFS명령줄에서 직접 단어에 대해 작동했습니다. 이렇게 설정하면 print IFS=b가 됩니다 .)echo foobarfoo ar

관련 정보