2014-09-08 1 views
1

cat이 파이프를 통해 공급되는 경우에만 쉘 스크립트를 종료하는 이유는 무엇입니까? 이제고양이가 쉘 스크립트를 종료하는 이유는 무엇입니까?

foo 

: 하나의 행이 포함

#! /bin/sh 
echo $# 
echo [email protected] 
cat $1 
sed -e 's|foo|bar|g' $1 

그리고 "에 foo.txt"라는 텍스트 파일 :

적절한 예는, "foobar.sh"이라는 쉘 스크립트를 가지고 나는 일반 경우

1 
foo.txt 
foo 
bar 

: 나는 명령 행에 ./foobar.sh foo.txt를 입력하면, 나는이 예상 출력을 얻을 수 있습니다 e cat foo.txt | ./foobar.sh 놀랍게도 나는이 출력만을 얻는다 :

나는 이해할 수 없다. 인수가 $# 인 경우 0이 있으면 cat $1은 여전히 ​​foo을 반환 할 수 있습니까? 그리고, 그렇다면 왜 sed -e 's|foo|bar|g' $1은 $ 1이 foo이므로 분명히 반환하지 않습니까?

이것은 버그와 굉장히 비슷해 보이지만, 나는 그것이 마법이라고 가정하고 있습니다. 설명 해주십시오!

#! /bin/sh 
if [ $# ] 
then 
yay=$(cat $1) 
else 
read yay 
fi 
echo $yay | cat 
echo $yay | sed -e 's|foo|bar|g' 

답변

3

아니요, $ 1은 (는) "foo"가 아닙니다. $ 1은 (는)

입니다. 즉, 정의되지 않음/아무 것도 아닙니다.

프로그래밍 언어와 달리 쉘의 변수는 문자 그대로 바뀌고 문자 그대로 바뀝니다. 결과 명령이 텍스트로 실행됩니다 (잘, 일종의). 이 경우 "cat $ 1"은 "cat"이되고, 표준 입력에서 가져옵니다. 파이프를 통해 stdin에 "foo"를 친절하게 제공했기 때문에 실행에 매우 편리합니다!

무슨 일이십니까?

sed도 stdin에서 읽지 만 이미 스트림의 끝 부분에 있으므로 종료됩니다.

+0

그렇다면 표준 입력란을 통해 보낸 내용을 어떻게 알 수 있습니까? 거기에 환경 변수가 있습니까? – CommaToast

+0

아니요. 재미있는 게임이 있지만 일반적으로 스트림의 소비자 만 스트림에 무엇이 있는지 볼 수 있습니다. 리터럴 파이프라고 생각하십시오. 한쪽 끝에서 물건을 채우면 다른 쪽에서 나옵니다. 내부에서 일어나는 일은 투명하지 않습니다. 당신은 볼 수 없습니다. – BadZen

+0

글쎄, 나는 stdin을 var에 할당하고 거기에서부터 읽기 명령을 사용할 수있다. 내 질문을 업데이트했습니다 ... – CommaToast

2

것은 당신에 대한 인수를 포기하지 않는다 : 주어진 답변에 따라

UPDATE

다음 스크립트는 한 줄에 foo.txt 가정, 예상되는 출력을 제공 cat, stdin에서 읽습니다. $1이 지정되지 않은 경우 cat $1은 (cat foo.txt)에 파이프 된 텍스트를 읽는 간단한 cat과 동일합니다.

그런 다음 sed 명령이 실행되고 cat과 동일하게 파일 이름 인수가 없기 때문에 stdin에서 읽습니다. cat은 이미 모든 stdin을 소비했습니다. 읽어야 할 것이 아무것도 없으므로 어떤 것도 인쇄하지 않고 sed이 종료됩니다.

관련 문제