Heredocs에 대한 입력에 작은따옴표 사용

Heredocs에 대한 입력에 작은따옴표 사용

tcsh 스크립트를 디버깅하는 데 도움이 필요합니다. heredocs를 사용합니다. 암호:

<pre_setup> <<EOF1
<setup> <<EOF2

<command>

exit 0
EOF2
exit 0
EOF1

이는 <pre_setup>사전 설정된 명령(예 wash: )과 setup그 이후에 실행되는 일부 설정입니다. 작동하지만 setup작은따옴표가 포함되면 실패하는 것으로 나타났습니다. 내 설정은 다음과 같습니다.

run_setup -cmd '$SOME_ENV -o outdir'

다음 을 설정 run_setup하고 $SOME_ENV실행 $SOME_ENV -o outdir하십시오.

wash -n group_name <<EOF1
run_setup -cmd '$SOME_ENV -o outdir' <<EOF2

<command>

exit 0
EOF2
exit 0
EOF1

실패하다 SOME_ENV: Undefined variable.. (또는 ) as를 사용하면 여전히 동일한 오류로 실패하기 때문에 washin에서는 문제가 되지 않습니다 . 이는 heredocs가 작동하는 방식과 관련이 있습니다. 어떻게 작동하게 할 수 있나요? 탈출의 문제인가? 이 문서를 어떻게 디버깅할 수 있나요?pre_setupsetenv X 1catpre_setup

run_setup -cmd '$SOME_ENV -o outdir'또한 쉘에서 실행하면 작동한다는 점도 언급하고 싶습니다 . 아니면 달리기만 pre_setup하면 setup됩니다. 그래서 이것은 heredocs와 관련이 있습니다.

편집하다: 따옴표로 묶어 다음과 같이 코드를 분리합니다.

/bin/tcsh <<EOF
$WORK_AREA/script.sh.$1
echo \$status > $WORK_AREA/.$1.result
exit 0
EOF

여기서 $1$는 this가 포함된 스크립트에 대한 입력입니다 heredocs. 작은따옴표로 묶인 경우 $1in $WORK_AREA/script.sh.$1은 비어 있습니다. 그러나 따옴표가 없으면 작동합니다. 왜? 어떻게 해결할 수 있나요?

답변1

일반 here-doc은 변수 등을 확장한다는 점에서 큰따옴표로 묶인 문자열과 약간 비슷합니다.

foo=there
cat <<EOF
hello $foo
EOF

"안녕하세요"를 출력합니다. sh-likes에서는 변수가 정의되지 않은 경우 일반적으로 오류가 발생하지 않고 빈 문자열만 표시됩니다.

인용문은 관련이 없습니다. 작은따옴표가 큰따옴표에서 특별하지 않은 것처럼 여기 문서에서는 특별하지 않습니다. 예를 들어 다음도 확장됩니다 $foo.echo "hello '$foo'"

확장을 방지하고 싶은 것 같으니 구분 기호를 인용하면 됩니다. 그러나 sh와 유사한 쉘과 (t)csh 사이에는 약간의 차이가 있는 것 같습니다.

sh-like에서는 다음과 같습니다.

foo=there
cat <<'EOF'
hello $foo
EOF

prints hello $foo, 즉 변수를 확장하려는 시도가 이루어지지 않습니다.

(t)csh에서는 같은 방식으로 닫는 구분 기호를 인용해야 하는 것 같습니다.

foo=there
cat <<'EOF'
hello $foo
'EOF'

이것데비안의 tcsh 매뉴얼 페이지설명하다:

<< word
다음과 동일한 줄이 나올 때까지 쉘 입력을 읽습니다.단어.단어변수, 파일 이름, 명령 대체의 영향을 받지 않으며 각 입력 라인은 다음과 동일합니다.단어이 입력 라인을 대체하기 전에.

\, "또는 인용되지 않은 '경우`단어[, ] 변수 및 명령 대체는 , 및 를 \인용하여 중간 줄에서 수행됩니다 .$\`

나는 "최대 한 줄이 동일하다"(및 "교체하기 전에 비교")는 참조가 동일하다는 것을 의미한다고 생각합니다. (이것은 Bash 매뉴얼 페이지에서 말하는 것과 다릅니다: "만약단어따옴표가 붙은 경우 구분 기호는 따옴표를 제거한 결과입니다.단어, [...]".)

두 번째 부분은 POSIX sh와 동일합니다. 여기서 인용된 구분 기호는 문서 텍스트의 확장을 억제합니다.


이 문서에서 셸을 제공하면 모든 변수를 확장할 수 있는 2개의 셸이 제공됩니다. here-doc의 쉘을 빌드한 다음 내부 쉘을 실행하여 읽으십시오. 그들은 변수가 무엇인지에 대해 서로 다른 생각을 가질 수 있습니다. 예를 들어 내부 변수는 기본 스크립트에 대한 인수를 갖지 않습니다. 인용 및 이스케이프 처리에 따라 확장되는 변수가 결정됩니다.

따라서 이것을 실행하면:

#!/usr/bin/tcsh
set foo = outer
echo in outer shell, foo is: $foo

tcsh <<EOF
set foo = inner
echo "not escaped, outer shell expands: $foo"
echo "    escaped: inner shell expands: \$foo"
EOF

보이는 내부 껍질

set foo = inner
echo "not escaped, outer shell expands: outer"
echo "    escaped: inner shell expands: $foo"

첫 번째는 $foo이미 확장되어 있으며 백슬래시는 에서 확장됩니다 \$foo. 대신 이를 사용하면 <<'EOF'셸이 확장되지 않습니다.

따라서 여기서는 따옴표 없이 사용해야 하며 <<EOF, 원하는 일에 따라 모든 변수를 개별적으로 이스케이프 처리하거나 처리하지 않도록 주의해야 합니다.

관련 정보