You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在POSIX Shell脚本中能否将多个命令参数存入变量并在后续命令中展开?

在POSIX Shell脚本中能否将多个命令参数存入变量并在后续命令中展开?

当然可以,但这里有个容易踩坑的细节要注意:如果你的参数都是单字、不含空格或特殊字符,直接用普通变量存了再展开完全没问题,但如果参数里包含空格、引号或者通配符,普通变量的展开方式会把这些特殊字符当成参数分隔符,导致命令执行出错。

先看你给出的示例场景

你代码里的mode变量就是单字参数的情况,不管是+111还是/111,直接在find命令里用$mode展开完全正常:

rootname="$1"
case "$(uname)" in
    Darwin)
        mode='+111'
        ;;
    Linux)
        mode='/111'
        ;;
esac
# 这里直接展开mode没问题
find "$rootname" -perm "$mode"

但如果要存多个带特殊字符的参数怎么办?

POSIX标准的shell没有数组(像bash/zsh里的数组是扩展特性),所以咱们得用位置参数配合set命令来实现,这是POSIX兼容的通用方法:

比如你想给find添加多个参数,包括可能带空格的文件名或者复杂选项,可以这么写:

rootname="$1"
# 先清空位置参数列表
set --
# 逐个添加需要的参数
set -- "$@" -type f
# 根据系统添加权限参数
case "$(uname)" in
    Darwin)
        set -- "$@" -perm +111
        ;;
    Linux)
        set -- "$@" -perm /111
        ;;
esac
# 如果rootname不为空,添加路径参数
if [ -n "$rootname" ]; then
    set -- "$@" "$rootname"
fi
# 用"$@"展开所有参数,每个参数都会被正确识别
find "$@"

这里的核心是"$@"——它会把每个位置参数作为单独的项展开,不管参数里有没有空格、引号,都不会被错误拆分。

为什么普通变量不行?

举个反例:如果你尝试用普通变量存多个参数:

args="-type f -perm +111 '/path with spaces'"
find $args

执行时shell会把'/path with spaces'拆成三个参数:'/path、with、spaces',完全不是你想要的效果。而用set和"$@"就能完美避免这个问题。

备注:内容来源于stack exchange,提问作者PRouleau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 10:15:32