스크립트 호출에서 변수를 반복 매개변수로 변환하는 가장 효율적인 방법을 알려줄 수 있는 사람이 있나요? 나는 그것을 적절하게 설명하는 방법을 모르지만 예제는 그 자체로 말해줍니다. 적어도 나는 그들이 그러기를 바란다 :)
예시 1:
# input
export DOMAINS="domain1.tld,domain2.tld"
# tranform to
./example-script.sh -d "domain1.tld" -d "domain2.tld"
예 2(입력은 홀수임):
# input
export DOMAINS="domain1.tld"
# tranform to
./example-script.sh -d "domain1.tld"
[업데이트] 첫 번째 게시물에 이 내용을 추가하지 못해 죄송합니다.
추가해야 할 컨텍스트:
- DOMAINS는 Docker 컨테이너에 추가된 환경 변수입니다.
sh
컨테이너에는 셸만 있으므로zsh
특정bash
옵션은 효과가 없습니다.- 초기
bash
태그를 추가해서 죄송합니다.
답변1
다음을 사용하는 것이 더 쉽습니다 zsh
.
분리된 목록을 포함하는 스칼라 변수에서 ,
:
DOMAINS="domain1.tld,domain2.tld"
s
배열로 분할 ,
:
domains=( ${(s[,])DOMAINS} )
압축배열 opt=( -d )
:
opt=( -d )
./example-script.sh ${opt:^^domains}
이것이 외에 지원되는 경우 ./example-script.sh
중간 배열을 건너뛰고 다음을 사용할 수 있습니다.-ddomain1.tld
-d
domain1.tld
./example-script.sh -d$^domains
Bash에서는 루프를 사용할 수 있습니다.
IFS=, # split on ,
set -o noglob # disable glob
domains=( $DOMAINS ) # split+glob
args=()
for domain in "${domains[@]}"; do
args+=( -d "$domain" )
done
./example-script.sh "${args[@]}"
또는 셸 구문을 사용하여 코드를 생성할 수 있습니다.
IFS=, # split on ,
set -o noglob # disable glob
domains=( $DOMAINS ) # split+glob
if [ "${#domains[@]}" -gt 0 ]; then
printf -v args ' -d %q' "${domains[@]}"
else
args=
fi
shell_code="./example-script.sh$args"
eval -- "$shell_code"
이것이 추가로 지원되는 경우 ./example-script.sh
다음을 수행할 수도 있습니다.-ddomain1.tld
-d
domain1.tld
IFS=, # split on ,
set -o noglob # disable glob
domains=( $DOMAINS ) # split+glob
./example-script.sh "${domains[@]/#-d}"
-d
배열의 각 요소 앞에 추가합니다 $domains
.
표준에는 sh
배열이 없고 표준 read -A/-a
도 printf
없습니다 %q
(그리고 이를 확장으로 지원하는 구현이 항상 sh
호환 가능한 참조를 생성하는 것은 아닙니다). 대신 위의 첫 번째 bash 메서드를 사용할 수 있습니다 "$@"
.
IFS=, # split on ,
set -o noglob # disable glob
set --
for domain in $DOMAINS; do # split+glob
set -- "$@" -d "$domain"
done
./example-script.sh "$@"
또 다른 옵션은 분할을 호출 awk
하고 sh
호환 가능한 코드를 생성하는 것입니다.
eval "./example-script.sh$(
LC_ALL=C awk -v q="'" '
function shquote(s) {
gsub(q, q "\\\\" q q, s)
return q s q
}
BEGIN {
n = split(ENVIRON["DOMAINS"], domains, ",")
for (i = 1; i <= n; i++)
printf " -d %s", shquote(domains[i])
}'
)"
답변2
다음과 같이 시도해 보세요.
domains=( "domain1.tld" "domain2.tld" )
./example-script.sh $(printf -- '-d "%s" ' "${domains[@]}")
답변3
표시했으므로 bash
해당 셸에 대한 배열 기반 솔루션은 다음과 같습니다.
DOMAINS="domain1.tld,domain2.tld"
# Comma separated string to array
IFS=, read -r -a domains <<<"$DOMAINS"
# Array to parameter list
args=()
for domain in "${domains[@]}"; do args+=(-d "$domain"); done
그런 다음 해당 목록을 결과 명령에 삽입할 수 있습니다 "${args[@]}"
(큰따옴표 포함). 예를 들어,
./example-script.sh "${args[@]}"