쉘 스크립트 및 파이프의 동작에 대한 설명

쉘 스크립트 및 파이프의 동작에 대한 설명

다음 쉘 스크립트의 동작을 이해해야 합니다.

#!/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디렉토리이기 때문에 오류가 발생합니다.

$1echo는 include dir2와 마지막 more오류 로 예상한 대로 수행합니다 dir2. 표준 입력에서 아무 것도 읽지 않습니다.

답변2

차이점은 "논쟁"대"표준 입력".

당신이 실행할 때 echo dir1 | bash script.sh,$1 토론script.sh인수가 제공되지 않았기 때문에 귀하의 인수 는 항상 비어 있습니다( set -x처음에 인수를 추가하면 디버그 출력에서 ​​볼 수 있습니다). 응답 내용의 출처 dir1는 다음과 같습니다.표준 입력more인수가 제공되지 않으면 명령은 stdin을 읽습니다( $1비어 있음을 기억하세요).

cmd1 | cmd2작동 원리

파이프를 사용하는 경우:

  1. cmd2예, 하위 프로세스입니다 cmd1.
  2. 표준 입력은 다음과 cmd2같습니다."막힌"표준 출력에 cmd1.

Linux stdio lib는 파일 설명자를 통해 버퍼링된 스트림을 제공하므로 stdin 콘텐츠가 소비됩니다(즉, 한 번만 읽기).표준 입력이 열린 경우에만.

단계별 cmd1 | cmd2작업흐름

명령 예:

echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")

  1. echo dir1 |: 첫 번째 명령의 표준 출력에 " "를 씁니다 dir1\n. 명령은 에코되지 않지만 표준 입력 및 출력을 통해 버퍼링되며 표준 입력을 통해 하위 처리될 수 있습니다.
  2. echo "a": 표준 출력에 " a\n"를 씁니다.표준 입력을 읽지 않습니다!따라서 " dir1\n" 문자열은 여전히 ​​사용 가능합니다.
  3. read stdinvalue: EOL(또는 EOF)까지 stdin을 읽고 문자열을 bash 변수에 저장합니다.
  4. echo "$stdinvalue": stdinvalue 변수 값을 stdout에 씁니다.

관련 정보