cat에게 두 개의 heredoc이 주어지면 두 번째 문서만 출력합니다.
$ cat <<HERE
> adsf
> qwer
> HERE
adsf
qwer
$ cat <<HERE <<ALT
> qwer
> asdf
> HERE
> zxcv
> yuop
> ALT
zxcv
yuop
이는 구분 기호와 파일이 주어졌을 때에도 작동합니다. 파일과 구분 기호(역순)를 주면 여전히 파일만 출력한다는 것을 알았습니다. 그러나 cat 두 개의 파일을 제공하면 두 파일이 모두 올바르게 출력됩니다.
고양이는 왜 이런 행동을 할까요?
답변1
시스템에서 /dev/fd/x
:
cat - << E0 /dev/fd/3 3<< E3
foo bar
E0
bar baz
E3
즉, 두 개를 열어라.여기에 파일다른 파일 설명자에 있습니다. fd 0에서 열면 물론 마지막으로 열린 것이 이전 것을 덮어쓰게 됩니다.
위의 명령은 이와 같은 명령에 더 유용합니다 paste
.
다음 기능(기본적으로 활성화되고 다른 셸을 에뮬레이션할 때는 비활성화됨) zsh
에 유의하세요 . 입력의 파일 설명자를 여러 번 리디렉션하면 zsh는 해당 입력의 연결을 제공합니다(별도 프로세스의 파이프를 통해). 그래서 zsh에서는:MULT_IOS
unsetopt MULT_IOS
$ cat << E1 << E2
heredoc> foo
heredoc> E1
heredoc> bar
heredoc> E2
foo
bar
cat
stdin은 파이프이고 zsh는 파이프의 다른 쪽 끝에서 두 개의 here 문서 내용을 순서대로 제공합니다.
출력 리디렉션에도 비슷한 기능이 있습니다.
ls > a > b
ls
파이프 에 쓰는 동안 zsh는 동시에 a
쓰고 b
씁니다( 형식과 유사 tee
). 반면 다른 쉘의 ls
stdout은 단지 잘립니다 b
( a
절단되지만 기록되지는 않음).
답변2
cat
인수가 없으면 파일 끝까지 표준 입력(예: 파일 설명자 0)을 읽고 이를 표준 출력(예: 파일 설명자 1)에 복사합니다.
cat
하나 이상의 인수를 사용하면 해당 인수를 차례로 입력으로 열고 데이터를 표준 출력에 복사하려고 시도합니다. 이 경우 표준 입력을 무시하는데, ctrl예를 들어 다음을 수행한 후 +를 입력해야 하면 매우 짜증날 수 있으므로 좋은 것입니다 . 이는 파일 이름이 지정될 때 "여기" 문서가 무시되는 이유를 설명합니다. 특별한 경우로 "표준 입력"을 의미하는 것으로 해석되는 파일 이름을 제공할 수 있습니다.Dcat /etc/motd
cat
-
할 수 있는파일을 "여기" 문서와 병합합니다.
쉘은 파일을 명령에 표준 입력으로만 전달할 수 있으므로 두 개의 "여기" 문서를 명령에 전달하는 것은 의미가 없습니다. 실제로는 마지막 문서만 명령에 표준 입력으로 전달합니다.
답변3
명령의 표준 입력( stdin
)을 리디렉션하는 방법에는 여러 가지가 있습니다.
command <file
단순 리디렉션: stdin은 파일이 됩니다.command <&n
fd
다른 fd에 대해 반복: stdin은 n의 반복이 됩니다.command <<word
여기에 문서가 있습니다: stdin이 스크립트가 될 것입니다.word
other | command
파이프: stdin은 출력에서 옵니다.other
stdin이 하나만 있으므로 stdin으로의 리디렉션은 하나만 작동합니다. 간단한 규칙은 마지막 항목이 승리한다는 것입니다(비록 이것들은 모두 순차적으로 적용되지만 리디렉션에 fd 중복이 포함된 경우 중요합니다).
위의 마지막 형식은 여러 입력을 연결하는 간단한 방법을 제공합니다.
{ cat <<END; cat <<END; } | command
The first here-doc
END
The second here-doc
END
일부 쉘은 추가 형태의 리디렉션을 제공합니다. 예를 들어, bash
및 ksh
는 zsh
"여기 문자열" 제공을 허용합니다: command <<<word
.
답변4
어디에 유용한지는 모르겠지만:
cat <<HERE
qwer
asdf
$(cat <<ALT
zxcv
yuop
ALT
)
HERE