이 명령에 대한 bash 매뉴얼 페이지에서 read
:
표준 입력 또는 -u 옵션의 인수로 제공된 파일 설명자 fd에서 한 줄을 읽고, 위의 단어 분할에 설명된 대로 단어로 분할하고, 첫 번째 단어를 이름에 할당합니다.
이제 다음을 시도했습니다.
IFS=,
echo ' a b,c d'|read -n 4 x y
echo ".$x. .$y."
내 예상 결과는
. a b. .c d.
변경으로 인해 토큰화는 공백 대신 쉼표로 이루어져야 하지만 실제 출력은 다음과 같습니다.
.a. ..
이것은 나를 혼란스럽게 한다. 공백에서는 단어 분리가 여전히 수행되는 것처럼 보이지만 .a.
적어도 공백이 아닌 y
로 설정되어야 합니다 b
.
read
나는 매뉴얼 페이지에서 이 명령에 대한 설명을 잘못 이해했다는 느낌을 지울 수 없습니다 .
그런데 저는 bash 4.4.12를 사용하고 있습니다.
답변1
잘 작동합니다:
$ IFS=,; echo ' a b,c d' | { read x y; declare -p x y;}
declare -- x=" a b"
declare -- y="c d"
노트
명령문 은 파이프에 있으므로
read
명령문은 서브셸에 있습니다. 변수x
sum 의 범위는y
이 서브셸로 제한됩니다. 위에서는declare
명령문이 동일한 하위 쉘에 있도록 중괄호를 추가했습니다read
. 이렇게 하면 명령문 출력에 읽은 x 및 y 값이 표시됩니다.중괄호를 제거하면
declare
명령문은 더 이상 동일한 하위 쉘에 있지 않으며 및x
값은y
유지되지 않습니다. 관찰하다:$ x=hot; y=cold; IFS=,; echo ' a b,c d' | read -n 4 x y; declare -p x y declare -- x="hot" declare -- y="cold"
서브쉘 제한을 피하기 위해 here-string을 사용할 수 있습니다.
$ IFS=,; read x y <<<' a b,c d'; declare -p x y declare -- x=" a b" declare -- y="c d"
here-string을 사용하면 명령문이 기본 셸에 있고 및
read
값이 손실되지 않습니다.x
y
-n 4
제한read
은 4자입니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다. 관찰하다:$ IFS=,; echo ' a b,c d' | { read -n 4 x y; declare -p x y;} declare -- x=" a b" declare -- y=""
여기서는
x
4개의 문자가 모두 사용되고(공백은 문자로 간주됨) 문자는 읽혀지지 않습니다y
.~처럼페사, 또는 명령 실행을 위해 로컬로 쉘 변수를 할당할 수도 있습니다. IFS를 변경하면 후속 명령에서 원치 않는 부작용이 발생할 수 있으므로 이는 좋은 생각입니다. 그러므로:
$ IFS=, read x y <<<' a b,c d'; declare -p x y declare -- x=" a b" declare -- y="c d"
위 명령이 실행되면
IFS
이전 값으로 돌아갑니다.