[linux] 파이프에서 쉘 변수로 값 읽기

파이프에 들어가는 stdin의 데이터를 bash에 처리하려고하지만 운이 없습니다. 의미하는 바는 다음과 같은 일이 아닙니다.

echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=

echo "hello world" | read test; echo test=$test
test=

echo "hello world" | test=`cat`; echo test=$test
test=

출력을 원합니다 test=hello world. “”따옴표를 넣어도 "$test"작동하지 않습니다.



답변

사용하다

IFS= read var << EOF
$(foo)
EOF

다음 과 같이 파이프에서 수락하도록 속일 수 있습니다read .

echo "hello world" | { read test; echo test=$test; }

또는 다음과 같은 함수를 작성하십시오.

read_from_pipe() { read "$@" <&0; }

그러나 아무 의미가 없습니다-변수 할당이 지속되지 않을 수도 있습니다! 파이프 라인은 환경이 참조가 아닌 값으로 상속되는 서브 쉘을 생성 할 수 있습니다. 이것이 read파이프의 입력을 방해하지 않는 이유입니다 -정의되지 않았습니다.

참고로, http://www.etalabs.net/sh_tricks.html 은 bourne shells의 이상과 비 호환성과 싸우는 데 필요한 cruft 모음입니다.


답변

많은 데이터를 읽고 각 줄에서 별도로 작업하려면 다음과 같이 사용할 수 있습니다.

cat myFile | while read x ; do echo $x ; done

줄을 여러 단어로 나누려면 x 대신 다음과 같이 여러 변수를 사용할 수 있습니다.

cat myFile | while read x y ; do echo $y $x ; done

대안 적으로 :

while read x y ; do echo $y $x ; done < myFile

그러나 이런 종류의 일로 정말 영리한 일을 시작하기 시작하면 펄과 같은 스크립트 언어를 사용하는 것이 좋습니다.

perl -ane 'print "$F[0]\n"' < myFile

펄에는 상당히 가파른 학습 곡선이 있지만 (또는이 언어들 중 하나를 추측합니다) 가장 간단한 스크립트 이외의 것을하고 싶다면 장기적으로 훨씬 더 쉽다는 것을 알 수 있습니다. Perl Cookbook과 Larry Wall et al.의 The Perl Programming Language를 추천합니다.


답변

read파이프에서 읽지 않습니다 (또는 파이프가 서브 쉘을 작성하기 때문에 결과가 손실 될 수 있음). 그러나 Bash에서 here 문자열을 사용할 수 있습니다.

$ read a b c <<< $(echo 1 2 3)
$ echo $a $b $c
1 2 3

그러나에 대한 정보는 @chepner의 답변을 참조하십시오 lastpipe.


답변

이것은 또 다른 옵션입니다

$ read test < <(echo hello world)

$ echo $test
hello world


답변

Bash의 전문가는 아니지만 이것이 왜 제안되지 않았는지 궁금합니다.

stdin=$(cat)

echo "$stdin"

그것이 나를 위해 일한다는 하나의 라이너 증거 :

$ fortune | eval 'stdin=$(cat); echo "$stdin"'


답변

bash4.2 lastpipe에는 서브 쉘이 아닌 현재 쉘의 파이프 라인에서 마지막 명령을 실행하여 코드가 작성된대로 작동 할 수 있는 옵션이 도입되었습니다 .

shopt -s lastpipe
echo "hello world" | read test; echo test=$test


답변

쉘 명령에서 bash 변수로의 암시 적 파이프의 구문은 다음과 같습니다.

var=$(command)

또는

var=`command`

귀하의 예에서는 입력을 기대하지 않는 할당 문으로 데이터를 파이프합니다.