스크립트에는 다음과 같은 연관 배열이 있습니다.
declare -A VARS=( ["key1"]="value1" ["key2"]="value" )
이것을 다음 형식의 매개변수 목록으로 변환할 수 있는 명령이 있습니까?
--key1=value1 --key2=value2
수동으로 다시 작성할 필요가 없습니다.
--key1="${VARS[key1]}" --key2="${VARS[key2]}"
내가 염두에 두고 있는 사용 사례는 배열을 매개변수 목록으로 스크립트에 전달하는 것입니다.
my_script.sh $(to_param_list $VARS)
@Kusalananda의 답변에 대한 내 의견을 확장하기 위해 정확한 사용 사례는 다음과 같습니다. makeself를 사용하여 자동 추출 설치 프로그램을 빌드하는 스크립트가 있으며 스크립트는 구분할 몇 가지 매개 변수를 받습니다.
- 스크립트 자체의 매개변수
- 자동 추출 설치 프로그램 내의 설치 프로그램 매개변수
그런 다음 스크립트는 다음과 같이 설치 프로그램을 빌드합니다.
to_param_list installer_param_list installer_param_array
./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "${installer_param_list[@]}"
그러나 패키지 내에서 매우 간단한 설치 프로그램 스크립트를 사용하여 매개변수 전달을 테스트했습니다.
while ! -z "$1" ; do
echo "$1"
shift
done
다음과 같은 배열을 전달합니다.
installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )
결과는 다음과 같습니다.
--upgrade-to=19.3.0
--upgrade-from=19
.2.0
답변1
보조 기능이 있습니다:
#!/bin/bash
to_param_list () {
declare -n outlist=$1
declare -n inhash=$2
for param in "${!inhash[@]}"; do
outlist+=( "--$param=${inhash[$param]}" )
done
}
declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )
to_param_list list my_vars
my_script.sh "${list[@]}"
위 스크립트의 마지막 명령은 쓰기와 동일하게 확장됩니다.
my_script.sh "--key2=value" "--key1=value1"
이 to_param_list
기능은이름배열 변수 및이름배열 변수를 연결하고 이를 사용하여 함수에 두 개의 "nameref" 변수를 만듭니다(nameref는 bash
버전 4.3에서 도입되었습니다). 그런 다음 연관 배열의 적절한 형식의 키와 값으로 지정된 배열 변수를 채우는 데 사용됩니다.
함수의 루프는 "${!inhash[@]}"
연관 배열에서 개별적으로 참조되는 키 목록을 반복합니다.
함수 호출이 반환되면 스크립트는 배열을 사용하여 다른 스크립트나 명령을 호출합니다.
다음을 사용하여 위를 실행하십시오.
declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
스크립트가 출력됩니다.
Arg: --key2=some thing
Arg: --key3=* * *
Arg: --key1=hello world
이는 단어 분할이나 파일 이름 글로빙이 적용되지 않고 옵션이 생성되었음을 나타냅니다. 또한 연관 배열에서 키에 액세스하는 것은 상당히 무작위 순서로 발생하므로 키의 순서가 유지되지 않을 수도 있음을 보여줍니다.
결과가 단일 문자열이 되기 때문에 여기서는 실제로 명령 대체를 안전하게 사용할 수 없습니다. 따옴표 없이 두면 문자열은 공백 문자(기본적으로)로 분할되며, 이는 연관 배열의 키와 값도 분할합니다. 쉘은 또한 결과 단어에 대해 파일 이름 글로빙을 수행합니다. 큰따옴표 명령 대체는 도움이 되지 않습니다 my_script.sh
.하나의토론.
귀하의 질문에 대해makeself
:
스크립트 makeself
는 이를 수행하기 위해 설치 프로그램 스크립트에 대한 인수를 사용합니다.
SCRIPTARGS="$*"
그러면 매개변수가 문자열 $SCRIPTARGS
(공백으로 구분되어 연결됨)로 저장됩니다. 그런 다음 파일은 그대로 자동 압축 풀기 아카이브에 삽입됩니다. 옵션을 올바르게 구문 분석하려면재평가(이것은 설치 프로그램을 실행할 때의 경우입니다.)추가의매개변수를 적절하게 구분하기 위한 매개변수 값 내의 따옴표 세트입니다.
installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )
이것은 내 코드의 버그가 아닙니다. makeself
생산의 부작용일 뿐이죠쉘 코드사용자가 제공한 값을 기준으로 합니다.
이상적으로는 makeself
스크립트가 제공된 각 매개변수를 주변에 추가 따옴표로 묶어 작성해야 하지만 이는 사실이 아닙니다. 아마도 이것이 어떤 영향을 미칠지 알기 어렵기 때문일 것입니다. 대신 사용자가 이러한 추가 견적을 제공할 수 있습니다.
위에서 테스트를 다시 실행하지만 지금은
declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )
to_param_list list my_vars
printf 'Arg: %s\n' "${list[@]}"
생산하다
Arg: --key2='some value'
Arg: --key3='* * *'
Arg: --key1='hello world'
너는 볼 수있어이것들언제 문자열재평가쉘에서는 공백으로 분할되지 않습니다.
to_param_list
분명히 초기 연관 배열을 사용하고 다음을 변경하여 함수에 따옴표를 추가할 수 있습니다.
outlist+=( "--$param=${inhash[$param]}" )
입력하다
outlist+=( "--$param='${inhash[$param]}'" )
코드에 대한 이러한 변경 사항 중 하나는 옵션 값에 작은따옴표를 포함하므로 값의 재평가는 다음과 같습니다.필요한.