zsh将命令变量视为整串执行失败,求跨Shell兼容安全方案
跨Shell兼容的命令执行方案(无eval)
问题根源
zsh不会像bash/dash那样对未加引号的字符串变量自动分词,直接执行$command时,会把整个字符串当作单个命令路径查找,因此出现"找不到文件"的错误。而eval存在安全风险,可能执行变量中的恶意元字符,不推荐使用。
解决方案1:使用数组(推荐,直观易维护)
将命令和每个参数单独存入数组,通过数组展开执行,这是跨bash/zsh/dash的安全方案:
# 定义命令数组,每个元素对应命令或独立参数 command_args=(/sbin/traceroute -M tcp -f 255 -m 255 -q 1 -w 1 -p 80 google.fr) # 执行并捕获输出 result="$("${command_args[@]}")"
兼容性说明
- bash/zsh:完全支持数组及
${array[@]}的正确展开 - dash:0.5.7及以上版本支持数组,当前主流系统的dash均满足该版本要求
解决方案2:使用位置参数(极致兼容老版本shell)
如果需要兼容不支持数组的老旧dash版本,可以用位置参数模拟:
# 将命令和参数设置为位置参数 set -- /sbin/traceroute -M tcp -f 255 -m 255 -q 1 -w 1 -p 80 google.fr # 执行并捕获输出 result="$("$@")"
原理
set --会把后续内容赋值给位置参数$1、$2...$n,"$@"会将每个位置参数作为独立项展开,完全符合POSIX标准,兼容所有POSIX兼容shell。
内容的提问来源于stack exchange,提问作者Orsiris de Jong
相关产品推荐
相关产品推荐

