heredoc를 템플릿으로 사용하여 일부 콘텐츠를 생성하고 싶습니다.
passphrase=$(<passphrase) envsubst <<EOF
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
그리고 oc create -f -
.
뒤에 파이프를 추가하면 EOF
작동하지 않습니다.
변수 대체가 포함된 heredoc를 소비하는 항목으로 어떻게 파이프할 수 있나요?
답변1
EOF
먼저 바로 뒤에 있는 부분을 인용해야 합니다 <<
. 가장 자연스러운 방법은 <<"EOF"
, 그러나 <<E"OF"
심지어는 <<""EOF
그렇게 할 것입니다. 이것이 없으면 이미 확장된 envsubst
문자열을 얻게 됩니다 ${passphrase}
. envsubst
리터럴 $foo
이나 하위 문자열이 있는 문자열에 대해 작동 하므로 ${foo}
미리 확장하면 envsubst
아무 상관이 없습니다. 또한 귀하의 경우 셸은 ${passphrase}
빈 문자열로 확장될 가능성이 높습니다. 코드의 변수 정의는 envsubst
셸 자체가 아닌 에만 영향을 미치기 때문입니다. 같은 이름의 변수가 (실수로?) 쉘에 미리 설정되어 있지 않는 한.
이제 우리는 귀하의 명시적인 질문에 도달합니다. 원하는 명령으로 결과를 파이프할 수 있지만 여전히 최종 EOF를 별도의 줄에 유지해야 합니다. 이를 수행하는 한 가지 방법은 다음과 같습니다.
passphrase=$(<passphrase) envsubst <<"EOF" | oc create -f -
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
또는 서브셸에 있는 코드를 실행할 수 있습니다.
( passphrase=$(<passphrase) envsubst <<"EOF"
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
) | oc create -f -
메모배쉬 참조 매뉴얼라고
파이프라인의 각 명령은 자체 하위 셸에서 실행됩니다.
따라서 첫 번째 솔루션에서도 파이프 없이 파이프를 구성할 때 ( )
첫 번째 부분(이전 |
)은 어쨌든 서브셸에서 실행됩니다. 두 번째 해결책은 이 서브셸을 명시적으로 만듭니다. 명시적을 사용한 후 (
쉘은 명시적을 기다립니다 )
. 이를 통해 종료 뒤에 무언가를 배치할 수 있습니다 EOF
.
<<
놀랍게도 첫 번째 솔루션을 사용하더라도 단일 복합 명령에서 둘 이상의 여기 문서( )를 사용할 수 있습니다 . 이러한 리디렉션은 파이프에서는 거의 의미가 없지만 &&
및 에서는 유용할 수 있습니다 ||
.
command1 <<EOF && command2 <<EOF || command3 <<EOF
content1
EOF
content2
EOF
content3
EOF
명시적인 하위 쉘을 사용하여 동일하게 재정렬되었습니다.
( command1 <<EOF
content1
EOF
) && ( command2 <<EOF
content2
EOF
) || command3 <<EOF
content3
EOF
상황에 따라 다른 표기법보다 한 표기법을 더 선호할 수도 있습니다.
구체적인 예로 돌아갑니다. 서브 쉘을 사용하면 다음이 필요하지 않습니다 envsubst
.
( passphrase=$(<passphrase); oc create -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: openshift-passphrase
stringData:
passphrase: ${passphrase}
EOF
)
이 방법과 이전 두 방법 사이에는 흥미로운 차이점이 있습니다.
- 이번에는 하위 쉘 자체가 확장되어야 하므로
${passphrase}
그렇지<<EOF
않습니다<<"EOF"
. - 이것이 작동하려면 변수가 ; 뿐만 아니라 서브쉘에도 알려져야 합니다
oc
. 이는… passphrase=$(<passphrase) oc create -f - <<…
(세미콜론이 없음에 유의) 작동하지 않는다는 의미입니다. - 기술적으로 서브쉘에 없는 동일한 코드(예: 없이
( )
)도 작동하지만 변수는 메인 쉘에 남아 있습니다. 서브쉘에서 코드를 실행하면 변수가 함께 죽게 됩니다. 원본 코드에서는 변수가 기본 셸에 대해 설정되지 않았으므로 이것이 원하는 것이라고 생각합니다.