쉘 변수 이름을 다른 변수로 바꾸기

쉘 변수 이름을 다른 변수로 바꾸기

나는 bash한동안 변수 대체에 어려움을 겪었지만 이것을 알 수 없습니다 ...

명령 템플릿이 포함된 변수가 있습니다.

CMD_TMPL='sudo -u ${USER_NAME} ${USER_HOME}/script.sh'

변수 USER_NAMEsum은 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

(환경으로 내보낸 변수에 대해 변수 이름을 모두 대문자로 예약하는 것이 가장 좋습니다.)

관련 정보