프로세스 대체에서 표준 입력을 읽는 방법은 무엇입니까? [복사]

프로세스 대체에서 표준 입력을 읽는 방법은 무엇입니까? [복사]

제 생각에는표준 출력을 여러 명령으로 보내기, 그러나 프로세스 대체에서 stdin을 읽는 방법을 잘 모르겠습니다.

내 시도:

$ echo foo >(cat /dev/stdin) >(cat /dev/stdin)
foo /dev/fd/63 /dev/fd/62

$ echo foo >(cat -) >(cat -)
foo /dev/fd/63 /dev/fd/62

$ echo foo >(cat <&3) >(cat <&3) 3<&0
foo /dev/fd/63 /dev/fd/62
-bash: 3: Bad file descriptor
-bash: 3: Bad file descriptor

동일한 문제의 대체 버전:

$ cat file | tee &>/dev/null >(cmd1 /dev/stdin) >(cmd2 /dev/stdin)

이를 수행하는 올바른 방법은 무엇입니까?

답변1

이는 표준 입력에서 읽습니다.

echo foo | tee >(read line </dev/stdin; echo "internal $line")

프로세스 교체는 파일과 "똑같이" 동작한다는 점을 기억해야 합니다.
파일이 필요한 곳이면 어디든 사용할 수 있습니다. tee 명령은 파일에 쓸 것으로 예상합니다.
이 명령에서는 /dev/stdin에서 읽을 장치를 지정합니다. 이 간단한 예에서는 /dev/stdin을 삭제할 수 있으며 다음과 같이 작동합니다.

echo foo | tee >(read line; echo "internal $line")

귀하의 요구 사항을 올바르게 이해하면 다음과 같이 작동합니다.

$ echo foo | tee >(read a </dev/stdin; echo "a is $a") \
>(read b </dev/stdin; echo "b is $b") \
>(read c </dev/stdin; echo "c is $c")
foo
a is foo
c is foo
b is foo

혼란을 줄이기 위해 PS2 프롬프트를 생략했습니다. 각 프로세스 교체는 파일 사용을 대체합니다(예 tee FILE FILE ....: : ).

읽기가 첫 번째 명령일 필요는 없습니다.

$ echo foo > >(echo "hello" | read b; read a </dev/stdin; echo "a is $a") 
a is foo

여기서 "프로세스 대체"에는 리디렉션이 필요하므로
이 두 관용구가 사용됩니다 > >(.

간단한 에코는 사용된 fd의 번호(파일 이름)만 인쇄합니다.

$ echo >(echo "hello")
/dev/fd/63
hello

이는 다음과 유사합니다:

$ echo "$file"
filename

그러나 이것은 매우 다른 관용어입니다.

$ echo > "$file"

관련 정보