쉘 리디렉션: <<<'foo' 대 <(echo 'foo') [중복]

쉘 리디렉션: <<<'foo' 대 <(echo 'foo') [중복]

나는 두 가지 접근 방식을 모두 보았고 <<<'foo'이를 <(echo 'foo')에코 파이프( )의 대안으로 제안했습니다 echo foo | cat.

cat과 함께 이 두 구조를 사용하면 다음과 같은 결과를 얻습니다.

$ cat <<<'foo'
foo
$ cat <(echo 'foo')
foo

지금까지도 그렇습니다.

그러나 셸에서 직접 사용하면 차이점이 분명해집니다.

$ <<<'foo'
foo
$ <(echo 'foo')
zsh: permission denied: /dev/fd/12

저는 zsh를 사용하고 있는데 bash는 <<<이 경우를 다르게 처리하는 것 같습니다. 아무것도 인쇄하지 않고 이 경우 zsh와 같습니다 <().

하지만 실제로 내 질문을 제기하는 것은 한 가지 차이점입니다.

$ diff <<<"/mypath" <(pwd)
diff: missing operand after `/dev/fd/63'
diff: Try `diff --help' for more information.

이 두 가지 유형의 셸 리디렉션 간에는 근본적인 차이점이 있다는 것이 분명합니다. 누구든지 차이점을 설명할 수 있나요?

답변1

<<< text명령의 파일 설명자에 영향을 미치는 경우 리디렉션입니다(여기서는 0이지만 4<<< textfd 4에 영향을 줍니다).

while은 <(...)리디렉션이 아닌 확장/대체입니다. 파일 이름으로 확장됩니다. 명령에 삽입되면 명령에 전달되는 매개변수에 영향을 줍니다.

cat <(echo test)

cat인수와 유사한 파일을 사용하여 실행합니다 /dev/fd/12. 그리고 fd 12는 파이프의 읽기 끝에서도 열려 있습니다. catfd 12에서는 읽지 않지만 파일을 열면 /dev/fd/12fd 12와 동일한 파이프를 가리키는 새 fd(아마도 3)를 얻게 됩니다.

echo test백그라운드에서 실행되는 동안 fd 1은 동일한 파이프의 쓰기 끝 부분에 연결되므로 echo결국 cat해당 파이프를 통해 연결됩니다(통신 채널은 설정하기가 그보다 더 복잡하지만 echo text | cat).

cat <<< text

인수 없이 cat을 실행하고 fd 0을 열어 포함된 test\n.

zsh 설명

<<< test

~처럼

$NULLCMD <<< test

이는 리디렉션만 포함된 항목을 실행할 때마다 ( $NULLCMD일반적으로 ) 발생합니다( 리디렉션이 cat하나만 있는 경우 (일반적으로 호출기)가 사용되지 않는 한).<$READNULLCMD

존재하다:

<(echo text)

리디렉션은 없으며 단지 프로세스 대체가 있으며 /dev/fd/12 매개변수로 확장됩니다. 이것은 쉘에게 파일을 실행하도록 요청합니다.

zsh에서는 다음을 사용해도 실질적인 이점이 없습니다.

cat <(echo test)
cat < <(echo test)

초과하다

echo test | cat

Bash와 같은 다른 셸에서 이 구성을 볼 수 있습니다. 예를 들면 다음과 같습니다.

IFS= read -r var < <(echo text)

하지만 그 이유는 해당 쉘에서는 하위 프로세스에서 실행되기 echo text | IFS= read -r var때문에 작동하지 않기 때문입니다 . read그렇지 않다 zsh.

프로세스 대체는 표준 입력이 아닌 파일 이름을 통한 입력만 인수로 허용하는 명령과 diff <(cmd1) <(cmd2).

zsh사이의 한 가지 차이점 은 후자가 기다리지 않는다는 것입니다. 비록 두 가지 종료 상태를 모두 사용할 수 있게 만드는 경우에만 대기하고 들어갑니다. 와 비교됩니다.cmd1 | cmd2cmd2 < <(cmd1)zshcmd1cmd1cmd2cmd1 | cmd2$pipestatussleep 1 | unameuname < <(sleep 1)

cmd <<< foocmd입력을 찾아야 할 때 유용합니다( zsh여기서 문서와 같은 문자열은 파이프가 아닌 임시 파일을 사용하여 구현되기 때문입니다).

관련 정보