如何将命令存储在 shell 脚本的变量中?

新手上路,请多包涵

我想将稍后使用的命令存储在变量中(不是命令的输出,而是命令本身)。

我有一个简单的脚本如下:

 command="ls";
echo "Command: $command"; #Output is: Command: ls

b=`$command`;
echo $b; #Output is: public_html REV test... (command worked successfully)

但是,当我尝试一些更复杂的东西时,它会失败。例如,如果我使

command="ls | grep -c '^'";

输出是:

 Command: ls | grep -c '^'
ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
ls: cannot access '^': No such file or directory

如何将这样的命令(使用管道/多个命令)存储在变量中以供以后使用?

原文由 Benjamin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 608
2 个回答

使用评估:

 x="ls | wc"
eval "$x"
y=$(eval "$x")
echo "$y"

原文由 Erik 发布,翻译遵循 CC BY-SA 4.0 许可协议

不要 使用 eval !它具有引入任意代码执行的主要风险。

BashFAQ-50 - 我试图将命令放入变量中,但复杂的情况总是失败。

将它放在一个数组中并用双引号 "${arr[@]}" 扩展所有单词, 以免 IFS 由于 Word Splitting 而拆分单词。

 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 方式

# POSIX sh
# Usage: sendto subject address [address ...]
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[@]}"

原文由 Inian 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题