Bash:存储在变量中的命令未执行

时间:2018-04-20 20:51:34

标签: bash shell scripting

我有以下脚本文件int32_t parse_packet(NetworkClient &client, NetworkMessage &msg); class AbstractPacketHandler { public: virtual void on_packet(NetworkClient &client, NetworkMessage &msg); }; class ServerHandler : AbstractPacketHandler { void on_packet(NetworkClient& client, NetworkMessage& msg) override { switch(parse_packet(client, msg)) { case HelloConnectMessage::PROTOCOL_ID: printf("deserialized hellomsg: %d\n", msg.getHelloVar()); break; // More cases } } };

temp.sh

它会抛出此错误

#! /usr/bin/env bash
this_command="exec \"/bin/ls\""
$this_command

但如果我跑

./temp.sh: line 3: /home/user/"/bin/ls": No such file or directory

运行正常。 我可以知道问题是什么以及如何将该命令存储在变量中以运行? 感谢

2 个答案:

答案 0 :(得分:2)

双引号对shell来说是特殊的。如果输入

exec "/bin/ls"

“引用删除”开始了,shell真正看到的是两个单词,exec/bin/ls

如果您从变量运行相同的命令,则它是不同的:请参阅man bash中的“扩展”:

  

引用删除
         在前面的扩展之后,所有未加引号的字符\,'和'出现          不会导致上述扩展之一的结果被删除。

由于引号来自变量扩展,因此不会将其删除。

只需存储不带引号的命令:

this_command='exec /bin/ls'
$this_command

对于涉及包含空格的特殊字符或文件名的更复杂命令,使用数组变量似乎更好

command=(ls -d 'dir name containing spaces')
"{command[@]}"

请注意,在命令构造期间仍会评估通配符,而不是在命令运行时。

$ touch 'a b'
$ command=(ls *\ *)
$ cd ..
$ "${command[@]}"
ls: cannot access 'a b': No such file or directory

答案 1 :(得分:0)

问题是在将变量存储命令时使用那些嵌套引号。

对于这个简单的例子,你可以使用:

逃脱
#!/usr/bin/env bash
this_command="exec /bin/ls"
$this_command

虽然这不适用于更复杂的命令行。为此,最好使用shell数组:

#!/usr/bin/env bash

# store command line an array
cmd=(exec /bin/ls -l 'some file'*)

# execute command line
"${cmd[@]}"

此示例将在shell中运行以下命令:

ls -l 'some file'*

检查 BashFAQ/050: I'm trying to put a command in a variable, but the complex cases always fail!