我有以下脚本文件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
运行正常。 我可以知道问题是什么以及如何将该命令存储在变量中以运行? 感谢
答案 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!