在一个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
4条答案
按热度按时间sycxhyv71#
使用
eval
:nwwlzxa72#
如§3.1 "Why does
$var
wherevar="foo bar"
not do what I expect?" of the Z-Shell FAQ中所述,可以使用shwordsplit
shell选项告诉zsh
,您希望它用空格分割变量,并将它们视为多个单词,该页还讨论了您可能需要考虑的替代方法。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语义,包括变量插值、路径扩展、多个命令等,或者是否应该只扩展单词并将它们作为单个命令运行。b09cbbtk4#
前面的答案是正确的,对我有效的是zsh中的以下命令