쉘 스크립트의 키가 /bin/bash로 파이프될 때까지 기다립니다.

쉘 스크립트의 키가 /bin/bash로 파이프될 때까지 기다립니다.

다음 쉘 스크립트를 고려하십시오.

echo foo; read; echo bar

출력 "foo"를 실행하고 bash my_script리턴 키를 기다린 후 "bar"를 출력합니다.

이 방법으로 실행하면 제대로 작동하지만 /bin/bash로 파이프하면 더 이상 작동하지 않습니다.

$ echo 'echo foo;read;echo bar'|bash

키 누름을 기다리지 않고 "foo" 및 "bar"를 직접 출력합니다.

이렇게 사용하면 왜 더 이상 작동하지 않습니까?

파일 스크립트 파일과 /bin/bash에 파이프된 스크립트 문자열 형식으로 스크립트를 다시 작성하는 방법이 있습니까?

답변1

실제로는 매우 간단합니다. 먼저 기억된 설명자에 표준 입력을 유지해야 합니다.

exec 9<&0

거기. 사본을 만들었습니다. 이제 셸에서 명령을 파이프해 보겠습니다.

echo 'echo foo; read <&9; echo bar' | bash

...글쎄, 그건 쉽네. 물론 아직 끝나지 않았습니다. 우리는 그것을 청소해야합니다.

exec 9<&-

좋아요, 이제 끝났습니다.

하지만 명령을 조금만 그룹화하면 정리 작업을 피할 수 있습니다...

{ echo 'echo foo; read <&9; echo bar' | bash; } 9<&0

이 경우 설명자는 할당된 복합 명령이 유효한 경우에만 유효합니다.

답변2

bash 내장 명령은 read표준 입력(fd0)에서 데이터를 읽지만 bash 명령 자체가 표준 입력을 사용하기 때문에 표준 입력을 열 수 없습니다.

eval무엇을 통제 할 수 있나요?

eval 'echo foo;read;echo bar'

예: 표준 입력에서 읽어야 하는 쉘 스크립트를 파이프하는 다른 방법은 생각할 수 없습니다. 쉘에 파이프하면 쉘은 대화형이 아닙니다.

나는 표준 입력 파일 설명자를 복사하는 방법을 전혀 알지 못했습니다. 이에 대한 Mike의 답변을 참조하십시오.

그런데: 읽으면 무슨 일이 일어나는지 알 수 있어요

echo 'echo foo;read;echo bar'|strace bash

답변3

ikrabbe의 답변은 명령줄이 예상대로 작동하지 않는 이유를 정확하게 지적합니다. 명령줄에 대해 새 셸을 호출하는 일반적인 방법은 다음과 같습니다.

$ sh -c 'echo foo; read; echo bar'

물론 bash원할 경우 이를 사용할 수 있지만 한 줄 쉘 스크립트에서 수행하려는 작업의 98%는 일반 쉘에서 수행할 수 있습니다. ("plain old shell"은 "POS"의 약어입니다.)

귀하의 목표가 한 줄짜리 셸 스크립트를 일시 중지하고 사용자 입력(아마도 단지 확인/확인)을 기다리는 것이라면 아마도 이렇게 해야 할 것입니다. 목표가 셸 작동 방식을 더 잘 이해하는 것이라면 다음을 시도해 보세요.

$(echo 'echo foo; 읽기; echo "$REPLY bar"'; 에코 캔디) $(echo 'echo foo; 읽기; echo "$REPLY bar"'; 에코 캔디) |쉿
부자
캔디 바                               (기다릴 필요가 없습니다)
$

관련 정보