Shell-Script
將變數拆分為 sh 中的命令選項參數
誰能告訴我在腳本呼叫中將變數轉換為重複參數的最有效方法?我不知道如何正確描述它,但例子不言自明。至少我希望他們這樣做:)
範例 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"
$$ UPDATE $$ 我很抱歉沒有在第一篇文章中添加這個。 我應該添加的上下文:
- DOMAINS 是添加到 Docker 容器的環境變數
- 容器只有
sh
外殼,因此zsh
特定bash
選項不起作用。- 很抱歉添加了初始
bash
標籤。
它更容易
zsh
:從包含
,
-separated 列表的標量變數中: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[@]}"
或者,您可以使用 shell 語法生成程式碼:
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]) }' )"