2개의 쉘 스크립트가 있습니다. 첫 번째는 두 번째를 트리거하고 일부 매개변수를 추가합니다. 두 번째 스크립트는 명령을 호출하고 첫 번째 스크립트의 매개변수를 명령에 대한 인수로 추가합니다.
첫 번째는 다음과 같습니다.
#!/usr/bin/env bash
ADDITIONAL_ARGUMENTS='--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'
SUPER_PARAMS=${ADDITIONAL_ARGUMENTS} my_second_script.sh
그런 다음 두 번째 스크립트는 다음을 수행합니다.
#!/usr/bin/env bash
randomBinary --some-hardcoded-parameters \
"${SUPER_PARAMS}"
내가 기대하는 결과는 다음과 같습니다.
randomBinary --some-hardcoded-parameters --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"
그러나 대신 호출은 다음과 같습니다.
randomBinary --some-hardcoded-parameters '--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'
매개변수를 올바르게 인용하려고 이틀 동안 노력했지만 결과가 없습니다.
답변1
여러 매개변수를 저장하려면 스칼라 변수 대신 배열을 사용하십시오.
additional_arguments=(
--set
'args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}'
)
randomBinary --some-hardcoded-parameters "${additional_arguments[@]}"
환경 변수는 NUL이 아닌 바이트의 문자열이므로 배열 정의를 환경을 통해 다른 명령에 전달하려면 일부 인코딩이 필요합니다.
ksh
, bash
또는 다음 zsh
을 yash
사용할 수 있습니다.
ARRAY_DEFINITION="$(typeset -p additional_arguments)" my_second_script.sh
배열 정의를 호출 스크립트의 환경 변수로 내보냅니다.
그리고 eval "$ARRAY_DEFINITION"
호출 스크립트에서수입배열 정의.
코드가 생성된 로캘과 동일한 로캘에서 동일한 셸을 사용하여 코드를 평가하는 것이 중요합니다.
또한 배열 정의가 함수 내에서 평가되는 경우 배열은 해당 함수에 대해 로컬이 됩니다.
일부 쉘은 배열 내보내기(내부적으로 자체 인코딩 사용)를 선호하거나 rc
허용 합니다.es
fish
여기서는 정보를 호출된 스크립트에 매개변수로 전달하는 것이 배열이기 때문에 더 쉬울 것입니다.
호출 스크립트에서:
my_second_script.sh "${additional_arguments[@]}"
호출 스크립트에서:
randomBinary --some-hardcoded-parameters "$@"
또는 호출자의 셸 변수를 공유하도록 호출된 스크립트를 호출하면 .
실행 중에 해당 데이터를 전달하기 위해 환경을 사용할 필요가 없습니다.
답변2
여기,
randomBinary --some-hardcoded-parameters "${SUPER_PARAMS}"
SUPER_PARAMS
포함 --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"
하고 인용되었으므로 있는 그대로 전달됩니다. 따옴표가 없으면 공백을 기준으로 5 개의 문자열 --set
, "args={/bin/bash,-c,cd
, /var/www
, 로 분할되고 이러한 문자열은 인수로 전달됩니다.&&
sudo -u www-data bash scripts/system/update.sh}"
변수 내부의 따옴표도 해석되기를 원하는 것 같습니다. 이를 위해서는 또 다른 쉘 구문 분석 계층을 추가하거나 eval
또는를 통해 해당 항목을 실행해야 합니다.bash -c '...'
테스트 스크립트는 다음과 같습니다.
$ cat test.sh
#!/bin/bash
ARGS='--set "args={this, that && that}"'
./args.sh $ARGS
eval "./args.sh $ARGS"
인쇄:
<!-- language: lang-none -->
$ bash test.sh
5 args: <--set> <"args={this,> <that> <&&> <that}">
2 args: <--set> <args={this, that && that}>
( args.sh
스크립트에 의해 인쇄되는 숫자는 다양한 매개변수의 수이며, 매개변수 자체는 에 인쇄됩니다 <...>
.)
예를 들어 eval
명령 대체를 수행하므로 임의의 코드 실행이 열립니다. 일반적으로 자신의 주장을 다음과 같이 설명하는 것이 가장 좋습니다.쉘 배열대신, 여기서는 한 스크립트에서 다른 스크립트로 전달하므로 제대로 작동하지 않습니다. "변수에 명령을 저장하는 방법" 섹션을 참조하세요. 존재하다공백 처리에 대한 이 답변.
반품Bash 가이드의 분사set -x
, 이를 사용하여 쉘이 실제로 실행한 명령을 확인할 수도 있습니다 .