不要使用eval
!它有一个很大的风险,会引入任意代码执行。
BashFAQ-50 - 我试图将一个命令放在变量中,但复杂情况经常失败。
将其放入数组中,并使用双引号扩展所有单词 "${arr[@]}"
,以免让IFS
因分词而拆分单词。
cmdArgs=()
cmdArgs=('date' '+%H:%M:%S')
并查看数组内的内容。使用 declare -p
可以让你查看数组内的内容,其中每个命令参数都会被单独放在索引中。如果其中一个参数包含空格,则在添加到数组时内部加上引号将防止它因单词拆分而被分割。
declare -p cmdArgs
declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'
执行命令
"${cmdArgs[@]}"
23:15:18
或者完全使用一个bash
函数来运行该命令,
cmd() {
date '+%H:%M:%S'
}
并只需调用函数
cmd
POSIX sh
没有数组,所以你能接近的是在位置参数中构建元素列表。这是一个 POSIX sh
执行邮件程序的方法。
sendto() {
subject=$1
shift
first=1
for addr; do
if [ "$first" = 1 ]; then set --; first=0; fi
set -- "$@" --recipient="$addr"
done
if [ "$first" = 1 ]; then
echo "usage: sendto subject address [address ...]"
return 1
fi
MailTool --subject="$subject" "$@"
}
请注意,此方法只能处理没有重定向、管道、for/while循环、if语句等的简单命令。
另一个常见用例是在运行带有多个标头字段和有效负载的curl时。您可以像下面这样定义args,并在扩展的数组内容上调用curl
curlArgs=('-H' "keyheader: value" '-H' "2ndkeyheader: 2ndvalue")
curl "${curlArgs[@]}"
另一个例子,
payload='{}'
hostURL='http://google.com'
authToken='someToken'
authHeader='Authorization:Bearer "'"$authToken"'"'
现在变量已经定义好了,使用数组来存储你的命令参数。
curlCMD=(-X POST "$hostURL" --data "$payload" -H "Content-Type:application/json" -H "$authHeader")
现在进行正确的引用扩展
curl "${curlCMD[@]}"