shell zsh是否运行存储在变量中命令?

wqsoz72f  于 2023-01-17  发布在  Shell
关注(0)|答案(4)|浏览(113)

在一个shell脚本(在. zshrc中)中,我正在尝试执行一个存储在另一个变量中的字符串命令。网络上的各种来源都说这是可能的,但是我没有得到我所期望的行为。也许是命令开头的~,或者是sudo的使用,我不确定。有什么想法吗?谢谢

function update_install()
{
    # builds up a command as a string...
    local install_cmd="$(make_install_command $@)"
    # At this point the command as a string looks like: "sudo ~some_server/bin/do_install arg1 arg2"
    print "----------------------------------------------------------------------------"
    print "Will update install"
    print "With command: ${install_cmd}"
    print "----------------------------------------------------------------------------"
    echo "trying backticks"
    `${install_cmd}`
    echo "Trying \$()"
    $(${install_cmd})
    echo "Trying \$="
    $=install_cmd
}

输出:

Will update install
With command: sudo ~some_server/bin/do_install arg1 arg2

trying backticks
update_install:9: no such file or directory: sudo ~some_server/bin/do_install arg1 arg2
Trying $()
update_install:11: no such file or directory: sudo ~some_server/bin/do_install arg1 arg2
Trying $=
sudo ~some_server/bin/do_install arg1 arg2: command not found
sycxhyv7

sycxhyv71#

使用eval

eval ${install_cmd}
nwwlzxa7

nwwlzxa72#

§3.1 "Why does $var where var="foo bar" not do what I expect?" of the Z-Shell FAQ中所述,可以使用shwordsplit shell选项告诉zsh,您希望它用空格分割变量,并将它们视为多个单词,该页还讨论了您可能需要考虑的替代方法。

bejyjqdl

bejyjqdl3#

我相信这里有两个问题--第一个问题是install_cmd被解释为单个字符串,而不是一个带有3个参数的命令(sudo)。
最后一次尝试$=install_cmd实际上正确地解决了这个问题(尽管我将它写成${=install_cmd}),但是接着遇到了第二个问题:~some_server/bin/do_install不是已知命令。这是因为出于安全原因,sudo无法按照您的预期解释~;它将需要使用 shell 来评估它的参数(或者为~做一些特殊的大小写,这实际上不关sudo的事),这打开了一整罐蠕虫,可以理解,sudo尽力避免这些蠕虫。
这也是为什么它可以执行eval ${install_cmd}--因为这实际上是将整个字符串视为一个要评估的对象,可能包含多个命令(例如,如果install_cmd包含echo foo; sudo rm -rf /,它会很乐意擦除系统)。
您必须自己决定是否希望install_cmd允许完整的shell语义,包括变量插值、路径扩展、多个命令等,或者是否应该只扩展单词并将它们作为单个命令运行。

b09cbbtk

b09cbbtk4#

前面的答案是正确的,对我有效的是zsh中的以下命令

totalin=$(eval echo testing |wc -l)
echo "Total: $totalin"

相关问题