나는 bash
한동안 변수 대체에 어려움을 겪었지만 이것을 알 수 없습니다 ...
명령 템플릿이 포함된 변수가 있습니다.
CMD_TMPL='sudo -u ${USER_NAME} ${USER_HOME}/script.sh'
변수 USER_NAME
sum은 USER_HOME
나중에 스크립트에서 계산되며 아직 CMD_TMPL
정의된 것으로 알려져 있지 않습니다. 따라서 명령은 작은따옴표로 묶여 있으며 대체되지 않았습니다.
그런 다음 스크립트는 내가 포함할 작업을 수행하고 싶다는 USER_NAME=test
것을 이해합니다 .USER_HOME=/home/test
${CMD}
sudo -u test /home/test/script.sh
아래 스크립트에서는 파이프라인에서 명령을 사용합니다. 예를 들면 다음과 같습니다.
${CMD} | output-processing.sh
변수 이름에서 ${CMD_TMPL}
변수 값으로 확장을 구현하는 방법은 무엇입니까 ${CMD}
? 나는 다양한 echo
와 '를 시도했지만 eval
알아낼 수 없습니다.
감사해요!
답변1
코드를 저장하는 데 사용되는 특별한 유형의 변수가 있습니다.기능:
cmd_tmpl() { sudo -u "$USER_NAME" "$USER_HOME/script.sh" "$@"; }
cmd() { cmd_tmpl other args "$@"; }
cmd | output_processing...
다른 접근 방식은 변수를 명령줄(셸 코드)로 처리하고 결국 다음을 사용하여 해당 코드를 해석하는 것입니다 eval
.
cmd_tmpl='sudo -u "$USER_NAME" "$USER_HOME/script.sh"'
cmd=$cmd_tmpl' other args as shell code'
eval "$cmd" | output_processing...
사용법 $cmd | output_processing
이 잘못되었습니다. $cmd
스칼라 변수이고, 분할+glob 연산자를 사용하여 간단한 명령의 인수 목록을 가져오면 여기에 저장된 명령줄을 평가하지 않습니다. 따라서 이는 제한된 조건에서만 작동합니다.
간단한 명령의 매개변수를 배열에 저장할 수 있습니다.
cmd=(sudo -u "$USER_NAME" "$USER_HOME/script.sh" ...)
"${cmd[@]}" | post_processing
그러나 이는 변수의 지연된 확장에는 도움이 되지 않습니다.
다음과 같은 방법으로 확장을 연기할 수 있습니다.
cmd_tmpl='sudo -u "$USER_NAME" "$USER_HOME/script.sh"'
...
eval "cmd=($cmd_tmpl)" # now expanded
cmd+=(other args)
"${cmd[@]}" | post-processing
(환경으로 내보낸 변수에 대해 변수 이름을 모두 대문자로 예약하는 것이 가장 좋습니다.)