다음 쉘 스크립트의 동작을 이해해야 합니다.
#!/bin/bash
echo "First more"
more $1
echo "First echo"
echo $1
echo "Second more"
more $1
다음 명령을 실행할 때:
echo dir1 | bash script.sh
나는 다음과 같은 결과를 얻습니다.
First more
dir1
First echo
Second more
왜 echo
그리고 두 번째로 more
접근할 수 없는 콘텐츠인가요 $1
?
다음 명령을 실행할 때:
echo dir1 | bash script.sh dir2
나는 다음 명령을 얻습니다
First more
dir1
*** dir2: directory ***
First echo
dir2
Second more
*** dir2: directory ***
dir2
모든 명령에 전달되지만 더 많은 것은 인쇄되지만 디렉토리 dir1
로 간주됩니다 .dir2
답변1
매개변수와 표준 입력을 혼동하고 있습니다. 데이터를 프로그램에 파이프하는 것은 명령줄 인수를 제공하는 것과 다릅니다.
첫 번째 경우에는 스크립트에 매개변수를 전달하지 않고 표준 입력 스트림을 통해 데이터를 공급하기만 하면 됩니다. 따라서 $1
스크립트 전체 기간 동안 설정되지 않습니다. 따라서
첫 번째 호출에서는 more
인수를 사용하지 않고 표준 입력을 페이징합니다. 그러면 ( dir1
, 텍스트로) 파이프한 내용이 표시됩니다 . 다음 항목은 echo
인쇄할 내용이 없기 때문에 새 줄만 인쇄하고 마지막 항목 more
도 인쇄할 항목이 없습니다. 표준 입력은 첫 번째 입력에 의해 "소진"되었습니다.
두 번째 경우에는 매개변수를 전달합니다. 스크립트의 $1
값도 마찬가지입니다 . dir2
처음 두 가지를 제외하고 동일한 일이 발생합니다 more
.
- 두 개의 표준 입력을 통한 페이징
- 파일을 페이징하려고 하는데
dir2
디렉토리이기 때문에 오류가 발생합니다.
$1
echo는 include dir2
와 마지막 more
오류 로 예상한 대로 수행합니다 dir2
. 표준 입력에서 아무 것도 읽지 않습니다.
답변2
차이점은 "논쟁"대"표준 입력".
당신이 실행할 때 echo dir1 | bash script.sh
,$1
토론script.sh
인수가 제공되지 않았기 때문에 귀하의 인수 는 항상 비어 있습니다( set -x
처음에 인수를 추가하면 디버그 출력에서 볼 수 있습니다). 응답 내용의 출처 dir1
는 다음과 같습니다.표준 입력more
인수가 제공되지 않으면 명령은 stdin을 읽습니다( $1
비어 있음을 기억하세요).
cmd1 | cmd2
작동 원리
파이프를 사용하는 경우:
cmd2
예, 하위 프로세스입니다cmd1
.- 표준 입력은 다음과
cmd2
같습니다."막힌"표준 출력에cmd1
.
Linux stdio lib는 파일 설명자를 통해 버퍼링된 스트림을 제공하므로 stdin 콘텐츠가 소비됩니다(즉, 한 번만 읽기).표준 입력이 열린 경우에만.
단계별 cmd1 | cmd2
작업흐름
명령 예:
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
echo dir1 |
: 첫 번째 명령의 표준 출력에 " "를 씁니다dir1\n
. 명령은 에코되지 않지만 표준 입력 및 출력을 통해 버퍼링되며 표준 입력을 통해 하위 처리될 수 있습니다.echo "a"
: 표준 출력에 "a\n
"를 씁니다.표준 입력을 읽지 않습니다!따라서 "dir1\n
" 문자열은 여전히 사용 가능합니다.read stdinvalue
: EOL(또는 EOF)까지 stdin을 읽고 문자열을 bash 변수에 저장합니다.echo "$stdinvalue"
: stdinvalue 변수 값을 stdout에 씁니다.