매뉴얼에 따르면:
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
인쇄합니까 ?XYZ
sssssssssssssssXYZ
s
매개변수 확장, 명령어 확장, 산술 확장 결과에만 영향을 미치기 때문일까요?
그렇다면 왜 선행 공백 문자를 에코 인쇄하지 않습니까?
답변1
많은 이유.
첫째, 토큰화는 IFS
명령줄(*)의 텍스트에 직접 적용되지 않고 확장된 결과에만 적용됩니다. 명령줄을 단어로 나누는 것은 다르며, 따옴표가 없는 연속 공백은 거기에 있는 공백과 동일합니다. 에서는 하나의 매개변수 somecmd foo:bar
를 somecmd
가져오는 반면 에서는 콜론 또는 공백 포함 somecmd foo bar
여부에 관계없이 IFS
두 개의 매개변수를 가져옵니다 . 에서는 단일 매개변수를 가져 echo xyz
옵니다 .echo
xyz
둘째, IFS
명령줄에서 구문 분석을 시작하기 전에 설정한 값이 중요합니다. 설정 var=foo:bar
하고 실행 하면 여전히 다음을 얻습니다 IFS=: printf "%s\n" $var
.printf
하나형식 문자열을 따르고 foo:bar
한 줄에 출력되는 매개변수입니다. 동일한 명령의 변수 설정은 해당 명령 내에서만 적용됩니다.~에그것을 사용하거나 사용 printf
하지 않습니다 .echo
IFS
이를 적용하려면 이전 명령을 설정해야 합니다 IFS
. 예를 들어 이렇게 하면 두 개의 개별 라인에 합계가 인쇄됩니다 foo
. 이렇게 하면 공백이 보존됩니다: .bar
var=foo:bar IFS=:; printf "%s\n" $var
var=" foo" IFS=:; printf "%s\n" $var
그러나 대부분의 경우 확장명을 인용하는 것이 더 좋습니다. 이렇게 하면 토큰화로부터 결과가 보호됩니다.그리고값에 관계없이 와일드카드입니다 IFS
.
(*AFAIK 일부 초기 쉘에서는 IFS
명령줄에서 직접 단어에 대해 작동했습니다. 이렇게 설정하면 print IFS=b
가 됩니다 .)echo foobar
foo ar