[bash] bash heredoc에서 변수 사용

bash heredoc 내부의 변수를 보간하려고합니다.

var=$1
sudo tee "/path/to/outfile" > /dev/null << "EOF"
Some text that contains my $var
EOF

예상대로 작동하지 않습니다 ( $var문자 그대로 처리되고 확장되지 않음).

sudo tee파일을 만들려면 sudo 가 필요하기 때문에 사용해야 합니다. 같은 일을 :

sudo cat > /path/to/outfile <<EOT
my text...
EOT

>outfilesudo를 사용하지 않는 현재 쉘에서 파일을 열기 때문에 작동 하지 않습니다.



답변

첫 번째 질문에 대한 답으로 구분 기호를 따옴표로 묶었으므로 매개 변수 대체가 없습니다 .bash 매뉴얼은 다음과 같이 말합니다 .

여기 문서의 형식은 다음과 같습니다.

      <<[-]word
              here-document
      delimiter

word 에서 매개 변수 확장, 명령 대체, 산술 확장 또는 경로 이름 확장이 수행되지 않습니다 . 단어의 문자 가 따옴표로 묶이면 구분 기호 는 단어에서 따옴표를 제거한 결과이며 여기 문서의 줄은 확장되지 않습니다. 단어 를 인용 부호로 묶지 않으면 여기 문서의 모든 줄에 매개 변수 확장, 명령 대체 및 산술 확장이 적용됩니다. […]

<<EOF대신 사용하도록 첫 번째 예를 변경 << "EOF"하면 작동한다는 것을 알 수 있습니다.

두 번째 예에서 셸은 sudo매개 변수로만 호출 cat하며 리디렉션 sudo cat은 원래 사용자 의 출력에 적용됩니다 . 시도하면 작동합니다.

sudo sh -c "cat > /path/to/outfile" <<EOT
my text...
EOT


답변

따옴표를 사용하지 마십시오 <<EOF:

var=$1
sudo tee "/path/to/outfile" > /dev/null <<EOF
Some text that contains my $var
EOF

변수 확장은 here-docs 내부의 기본 동작입니다. 레이블을 작은 따옴표 또는 큰 따옴표로 인용하여 해당 동작을 비활성화합니다.


답변

여기에 이전 답변에 늦은 corolloary으로, 당신은 아마 당신이 원하는 상황에서 결국 일부 가 아닌 모든 변수가 보간 될 수 있습니다. 백 슬래시를 사용하여 달러 기호와 백틱을 피함으로써이 문제를 해결할 수 있습니다. 또는 정적 텍스트를 변수에 넣을 수 있습니다.

Name='Rich Ba$tard'
dough='$$$dollars$$$'
cat <<____HERE
$Name, you can win a lot of $dough this week!
Notice that \`backticks' need escaping if you want
literal text, not `pwd`, just like in variables like
\$HOME (current value: $HOME)
____HERE

데모 : https://ideone.com/rMF2XA

인용 메커니즘 중 \____HERE하나 "____HERE"또는 '____HERE'-또는는 모든 변수 보간을 비활성화하고 여기 문서를 리터럴 텍스트로 바꿉니다.

일반적인 작업은 로컬 변수를 스크립트와 결합하여 다른 쉘, 프로그래밍 언어 또는 원격 호스트에서 평가해야합니다.

local=$(uname)
ssh -t remote <<:
    echo "$local is the value from the host which ran the ssh command"
    # Prevent here doc from expanding locally; remote won't see backslash
    remote=\$(uname)
    # Same here
    echo "\$remote is the value from the host we ssh:ed to"
:


답변