当我使用以下命令时,一切都按预期工作(一个新的gnome-terminal打开,当前工作目录被更改,终端保持打开状态):
gnome-terminal -e "bash -c 'cd /';$SHELL"
# ↑
# no space character here
但是当我使用时:
gnome-terminal -e "bash -c 'cd /'; $SHELL"
# ↑
# note the space
我可以看到一个打开的终端,但是我看不到当前工作目录是否被更改,因为它立即关闭了终端。
我的问题是:为什么会这样;如果我在第二种情况下放一个空格怎么会错?
答案 0 :(得分:6)
在第一种情况下,gnome-terminal执行
bash -c "cd /;/bin/bash"
在第二种情况下,它运行
bash -c "cd /;" /bin/bash
第一种情况意味着“评估cd /;/bin/bash
”,它将cd并运行一个交互式shell。
第二种情况意味着“评估cd /;
,$0
设置为/bin/bash
”,这将运行cd然后退出。
答案 1 :(得分:3)
gnome-terminal
使用g_shell_parse_argv自行解析给定的命令,显然不会将;
视为单词分隔符,因此如果;
}与非空白字符相邻,它被认为是非空白字符的一部分。
如果传递给gnome-terminal
的命令中包含shell元字符,则会导致令人惊讶的行为。
我在strace
进程中使用gnome-terminal
来查看它的作用。第一个命令
gnome-terminal -e "bash -c 'cd /';$SHELL"
导致gnome-terminal运行以下命令
execve("/bin/bash", ["bash", "-c", "cd /;/bin/bash"])
第二个命令
gnome-terminal -e "bash -c 'cd /'; $SHELL"
导致gnome-terminal运行以下命令
execve("/bin/bash", ["bash", "-c", "cd /;", "/bin/bash"])
话虽如此,您还应该注意,bash -c 'cd /'
之类的命令不会对其后运行的任何命令的工作目录产生持久影响。所以我认为你键入的第一个命令得到了所需的结果只是因为gnome-terminal解析错误,并且更强大的编写方式将是
gnome-terminal -e "bash -c 'cd /;$SHELL'"