here-documents 및 cat과 함께 출력 리디렉션을 어떻게 사용합니까?


56

다른 명령으로 파이프하거나 파일로 리디렉션하려는 스크립트가 있다고 가정 해 보겠습니다 ( sh예를 들어 파이프 ). 내가 bash를 사용하고 있다고 가정하십시오.

나는 그것을 사용하여 그것을 할 수있다 echo:

echo "touch somefile
echo foo > somefile" | sh

또한 다음을 사용하여 거의 같은 작업을 수행 할 수 있습니다 cat.

cat << EOF
touch somefile
echo foo > somefile
EOF

그러나 "EOF"를 "EOF | sh"로 바꾸면 이것이 heredoc의 일부라고 생각합니다.

catstdin에서 텍스트 를 출력 한 다음 임의의 위치로 파이프를 만들려면 어떻게해야합니까?


touch거기에 있지 않으면 정확히 무엇을 원하는가? 입력 파일을 읽고 stdout을 사용하여 다른 파일로 리디렉션합니까?
Rahul Patil

2
@RahulPatil 물론 쓸모가 없습니다. heredoc을 더 잘 설명하기 위해 두 줄 이상의 예제가 필요했습니다. 그리고 사용하는 예제를보십시오 echo-이것과 동등한 것이 무엇인지 궁금합니다 cat.
strugee

귀하의 예는 sh여러 문자열 로 스크립트를 작성하여 직접 전달하는 것 sh입니다. Q는 HERE 문서를 포함하여 여러 명령의 텍스트 출력을 명령으로 직접 전달하려고합니다. Ash의 답변의 두 번째 예는 다음과 같습니다.
Dave X

답변:


91

여러 가지 방법이 있습니다. 가장 간단한 방법은 다음과 같습니다.

cat <<EOF | sh
touch somefile
echo foo > somefile
EOF

내 의견으로는 더 좋은 구문입니다.

(
cat <<EOF
touch somefile
echo foo > somefile
EOF
) | sh

서브 쉘 없이도 작동합니다.

{
cat <<EOF
touch somefile
echo foo > somefile
EOF
} | sh

더 많은 변형 :

cat <<EOF |
touch somefile
echo foo > somefile
EOF
  sh

또는:

{ cat | sh; } << EOF
touch somefile
echo foo > somefile
EOF

그건 그렇고, cat귀하의 질문에 사용하는 것이 다른 것에 대한 자리 표시 자라고 생각합니다. 그렇지 않은 경우 다음과 같이 꺼내십시오.

sh <<EOF
touch somefile
echo foo > somefile
EOF

이것으로 단순화 될 수 있습니다 :

sh -c 'touch somefile; echo foo > somefile'

또는:

sh -c 'touch somefile
echo foo > somefile'

배관 대신 출력 재 지정

sh >out <<EOF
touch somefile
echo foo > somefile
EOF

를 사용 cat하여 다음에 해당합니다 echo test > out.

cat >out <<EOF
test
EOF

여러 문서

( cat; echo ---; cat <&3 ) <<EOF 3<<EOF2
hi
EOF
there
EOF2

출력이 생성됩니다.

hi
---
there

진행중인 작업은 다음과 같습니다.

  • 쉘은를보고 ( ... )서브 쉘에서 동봉 된 명령을 실행합니다.
  • 고양이와 에코는 충분히 간단합니다. 는 cat <&3파일 기술자와 고양이를 실행 말한다 (FD) 0 (표준 입력) FD 3에서 재; 다시 말해, fd 3의 입력을 제거하십시오.
  • 시작하기 전에 (...)셸은 여기에있는 두 개의 문서 리디렉션을보고 fd 0 ( <<EOF) 및 fd 3 ( 3<<EOF2)을 파이프의 판독면으로 대체합니다.
  • 초기 명령이 시작되면 쉘은 EOF에 도달 할 때까지 stdin을 읽고이를 첫 번째 파이프의 쓰기 측으로 보냅니다.
  • 다음으로 EOF2 및 두 번째 파이프의 쓰기 측과 동일합니다.

두 번째부터 마지막까지의 예제에서 배관 대신 stdout 리디렉션을 사용하여 예제를 제공 할 수 있습니까?
strugee

리디렉션 예제를 사용하여 답변을 편집했습니다. 이 양식을 편집하고 싶습니까? 그렇지 않다면, 그 부분의 첫 줄을 명확히 해줄 수 있습니까?
ash

1
쉘이 이것을 어떻게 처리하는지 이해하는 것이 도움이 될 수 있습니다. 명령 줄을 평가할 때 << EOF를 찾으면 EOF 만있는 행이 있거나 입력 끝이 발견 될 때까지 표준 입력에서 읽습니다. 처리되지 않은 원래 명령 줄의 다른 모든 내용은 계속 처리됩니다. 예를 들어, 다음과 같은 작업을 수행 할 수 있습니다. (cat; echo ---; exec <&3; cat) <<EOF 3<<EOF2 >out그런 다음 행에 두 개의 here-blocks로 해당 명령 입력을 제공하십시오.
ash

쉘 처리 귀하의 설명은 흥미로웠다하지만 내 머리를 내가 어떻게 될지이었다 알고 싶어 무엇 :) cat의 상당 echo test > out히어 닥을 사용 할 것이다. 주어진 예제는 파이프 끝에 리디렉션을 추가했습니다.
strugee

1
@OlivierDulac-여러 heredoc 예제를 답변에 추가했습니다.
ash

1

사용하는 meow것만큼이나 유효 하다는 것을 지적하고 싶습니다 EOF.

이 스크립트는 다음 Meow!이름의 파일에 추가 됩니다 cat.

#!/bin/sh
cat <<meow>> cat
Meow!
meow

다른 이름으로 저장 cats하고 실행 파일로 chmod +x cats만든 다음 다음을 사용하여 실행하십시오 ./cats.

$ ./cats
$ cat cat
Meow!
$ ./cats
$ cat cat
Meow!
Meow!

설명:

  • cat <<meow는 IS 여기 문서 구문. 문자열에 도달 할 때까지이 행 다음에 오는 텍스트 블록을 선택하도록 스크립트에 지시합니다 meow. 그런 다음 내용이 출력됩니다 (또는 파이프로 연결됨).
  • >> cat라는 파일에 파이프합니다 cat.
  • >대신에 사용 >>하면 파일을 추가하는 대신 덮어 씁니다.
  • Meow!here 문서 의 내용입니다 .
  • meowhere 문서 의 끝 표시 자입니다 . 를 사용하여 내용이 >>에 추가됩니다 cat.

stdout 및 파일 모두에 파이프 :

요청한 배관을 수행하기 위해 여기에 문서 가 필요 하지 않습니다.

cat텍스트를 출력하고 텍스트를 전달할 수는 없지만 tee요청한 내용과 완벽하게 일치합니다.

echo echo | tee tee

문자열을 출력하고 라는 파일에 echo씁니다 .echotee

다음 cat중 하나를 사용하여 요구 사항의 일부인 경우 출력을 통해 전달할 수도 있습니다 .

echo echo | tee tee | cat </dev/stdin

아니면 그냥 :

echo echo | tee tee | cat

파일 내용 :

$ cat tee
echo

1
이것은 실제로 질문에 대답하지 않습니다. 또한 >마지막 글 머리 기호에서 알 수 있듯이 파이프를 만들지 않습니다.
strugee

2
@strugee 는 또는 에서와 동일한 fd가 여러 번 리디렉션 될 때 >파이프를 생성 할 수 있습니다 . 여기서 내부 와 내부 및 파일 모두에 출력 을 제공 합니다. zshecho foo >&1 > teeecho foo > tee | catzshteeechocattee
Stéphane Chazelas

질문에 더 잘 대답 할 수 있도록 내 답변을 업데이트했습니다.
Alexander
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.