파이프 및 리디렉션 이해

파이프 및 리디렉션 이해

이 스크립트를 설명해주세요(출처:ABSG. 장. 20):

exec 3>&1                              # Save current "value" of stdout.
ls -l 2>&1 >&3 3>&- | grep bad 3>&-    # Close fd 3 for 'grep' (but not 'ls').
#              ^^^^   ^^^^
exec 3>&-                              # Now close it for the remainder of the script

현재 나는 그것이 어떻게 작동하는지 상상합니다.

  1. fd/3 출력을 stdout에 연결하는 스크립트
  2. 파이프는 stdout을 lsstdin에 연결합니다 grep(두 프로세스 모두 fd/3을 상속함).
  3. lsstderr를 stdout으로 리디렉션
  4. stdout이 lsfd/3으로 변경됩니다(따라서 프로세스에서 grep더 이상 출력이 없고 오류만 발생함).ls
  5. fd/3이 닫혔습니다.ls

이것이 정확한 리디렉션 순서입니까?

lsif에서 오류 출력이 표시되지 않고 fd/3에 의해 리디렉션된 stdout을 닫는 이유를 이해할 수 없습니다 .

grepfd/3 종료 process() 의 목적은 무엇입니까 grep bad **3>&-**?

답변1

파일 설명자를 파일을 값으로 받아들이는(또는 I/O 스트림이라고 부르는) 변수로 생각하고 표시되는 순서가 평가되는 순서대로 생각하면 도움이 됩니다.

위의 예에서는 다음과 같은 일이 발생합니다.

1) 스크립트는 다음으로 시작합니다(상속되지 않는 한 기본적으로).

fd/0 = stdin    # that's the keyboard
fd/1 = stdout   # that's the screen
fd/2 = stderr   # the screen again, but different stream

2) 이 exec명령은 새로운 변수를 선언하고 값을 할당하는 것으로 해석됩니다.

fd/3 = fd/1  # same as stdout

이제 두 파일 설명자의 값은 stdout입니다. 즉, 둘 다 화면에 인쇄하는 데 사용할 수 있습니다.

3) ls열려 있는 모든 파일 설명자를 실행하고 상속하기 전에 다음 설정이 수행됩니다.

ls.fd/1 = grep.fd/0    # pipe gets precedence, ls.fd/1 writes to grep.stdin
ls.fd/2 = ls.fd/1      # ls.fd/2 writes to grep.stdin 
ls.fd/1 = ls.fd/3      # ls.fd/1 writes to stdout
ls.fd/3 = closed       # fd/3 will not be inherited by `ls`

fd/3의 목적은 표준 출력 값을 fd/1로 반환할 수 있을 만큼 오랫동안 유지하는 것입니다. 이제 lsfd/1로 전송된 모든 내용은 stdin 대신 stdout으로 전송됩니다 grep.

순서가 중요합니다. 예를 들어 ls -l >&3 2>&1 3>&-ls.fd/2를 실행하면 표준 입력 대신 표준 출력에 기록됩니다 grep.

4) fd/3 for grep는 닫혀 있고 상속되지 않습니다. 어쨌든 사용될 것입니다. grep오류 메시지만 필터링할 수 있습니다.ls

ABSG에 제공된 예는 가장 도움이 되지 않을 수 있으며 ""grep"에 대해 fd 3을 닫습니다(그러나 "ls"는 아님).”는 약간 오해의 소지가 있으므로 다음과 같이 읽을 수 있습니다.ls의 경우 설정을 해제하기 전에 ls.fd/3 값을 ls.fd/1에 전달하여 닫히지 않도록 합니다.".

관련 정보