간단한 고양이 에코 프로세스 교체가 중단됩니다.

간단한 고양이 에코 프로세스 교체가 중단됩니다.

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

당신이 무엇을 성취하고 싶은지는 모르겠지만,

  1. >(...)실행 중인 모든 항목의 표준 입력을 쓰기 가능하게 만듭니다.
  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거기에 두고 읽기가 완료될 때까지 기다리겠습니다. (여기 stracecat 여기 모두 파이프에 쓰기 위해 열려 있는 파일 핸들을 가지고 있지만 이는 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종료됩니다.

관련 정보