cat을 사용한 간단한 프로세스 교체가 중단된 것 같습니다.
cat >( echo hello; )
결코 끝나지 않습니다. 또한 시도했습니다:
cat >( echo hello; exit; )
하위 프로세스에서 stdout 파일 설명을 수동으로 닫는 것도 작동하지 않습니다.
cat >( echo hello; 1>&- )
cat >( echo hello; 1>&- exit; )
나는 GNU bash 버전 4.4.23(1)-릴리스, GNU bash, 버전 4.1.2(2)-릴리스 및 zsh 5.5.1(x86_64-debian-linux-gnu)을 사용해 보았습니다.
왜 이런 일이 발생하는지 설명할 수 있나요? 나는 프로세스 대체를 정말 좋아합니다 ...
감사해요
편집: cat이 echo에서 읽는 경우 프로세스 대체의 올바른 리디렉션은 다음과 같습니다.
cat <( echo hello; )
답변1
귀하의 코드는 cat >( echo hola; )
절대 종료되지 않습니다.
- 먼저 패턴을 에코합니다.
hola
- 쓰기를 위한 입력을 받아들입니다.
- 우리가 그것을 주면
Ctrl+D
쓸 파일을 계속 검색합니다.
옵션 1:에코된 파일에 컨텍스트 쓰기
cat > $( echo hola; )
따라서 아래에 제공하는 모든 컨텍스트는 hola
.
참고: 다음과 같이 cat 블록을 종료할 수 있습니다.Ctrl+D
옵션 2:에코된 컨텍스트를 캡처합니다.
cat <(echo hola;)
답변2
당신이 무엇을 성취하고 싶은지는 모르겠지만,
>(...)
실행 중인 모든 항목의 표준 입력을 쓰기 가능하게 만듭니다.cat
읽을 수 있는 파일이 필요합니다.
(1)에서 제공하는 내용을 읽을 수 있다는 보장은 없습니다. macOS에서는 오류가 발생했습니다.
bash-4.4$ cat >( echo foo)
foo
cat: /dev/fd/63: Permission denied
Linux에서는 다른 쪽 끝에 아무것도 쓰여 있지 않은 파이프입니다.
$ strace -e openat cat >(echo foo)
foo
...
openat(AT_FDCWD, "/dev/fd/63", O_RDONLY) = 3
그리고:
$ ll /proc/$(pgrep cat)/fd/3
lr-x------ 1 muru muru 64 Aug 13 18:55 /proc/3381/fd/3 -> 'pipe:[37501]'
$ lsof | grep 37501
strace 3433 muru 63w FIFO 0,12 0t0 37501 pipe
cat 3435 muru 3r FIFO 0,12 0t0 37501 pipe
cat 3435 muru 63w FIFO 0,12 0t0 37501 pipe
다른 쪽 끝이 stdin을 닫고 종료하는 것은 중요하지 않습니다. 파이프만 열면 됩니다.읽다, 아무 것도 기록되지 않으며 파이프에도 아무 것도 기록되지 않습니다. 그래서 cat
거기에 두고 읽기가 완료될 때까지 기다리겠습니다. (여기 strace
와 cat
여기 모두 파이프에 쓰기 위해 열려 있는 파일 핸들을 가지고 있지만 이는 bash가 쓰기 위해 파일 핸들을 열어서 사용할 수 있도록 만들었기 때문입니다. 둘 다 쓸 수 없습니다.)
답변3
프로세스 대체는 그 자체로 주제입니다. 알아야 할 중요한 점은 이것이 stdin이나 stdout보다 FIFO에 더 가깝다는 것입니다. echo를 사용하여 이를 확인할 수 있습니다.
echo >( echo hello; )
당신에게: /dev/fd/63 안녕하세요
외부 에코는 실제로 주어진 매개변수를 제공합니다 /dev/fd/63
. 그래서 당신의
cat >( echo hello; )
실제로 cat /dev/fd/43
출력은 으로 전송됩니다 echo hello
. (43은 예시일 뿐이며 숫자는 랜덤이지만 보통 63입니다.)
다음의 차이점도 확인할 수 있습니다.
echo hop > >(cat)
이것은 제공 hop
하고
echo hop >(cat)
이것은 만든다 hop /dev/fd/63
.
또한 예를 들면 다음과 같습니다.
sed 's/$/klap/' | tee >(sed 's/^/hop/')
의견을 제시하다klop
klopklap
hopklopklap
이것은 klopklap
표준 출력이며 tee
, 프로세스에서 대체된 표준 출력입니다 hopklopklap
.sed
그렇다면 왜 정지됩니까 cat >(echo hello)
? 앞서 언급했듯이 cat은 인수를 받고 /dev/fd/32
해당 "파일"에서는 EOF를 얻지 못하기 때문입니다.
답변4
정지 되지 cat
않고 사용자의 입력을 기다리고 있습니다. cat
표준 입력을 읽고 표준 출력에 씁니다. 표준 입력을 리디렉션하지 않으므로 표준 입력이 터미널입니다. 를 입력하면 Ctrl+D
파일의 끝을 나타내며 파일이 cat
종료됩니다.