我在用着这个方法打开 Gnome 终端窗口并运行命令 — 在本例中,是向我发送简单的通知消息(将通过 安排at
):
#!/bin/sh
gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash'
shell 仅打印remember:
字符串而不打印我指定的值,例如在运行remind.sh "pick up the package"
或时remind.sh "buy groceries X and Y"
。
当我将脚本剥离到其核心时,一切都按预期工作(当然,通过 cron 或 systemd 在自动化中没有任何用处,因为前台没有显示任何内容):
#!/bin/sh
echo "remember: $1"
答案1
分析
gnome-terminal
您(或者更确切地说,在您的情况下)提供的代码/bin/sh -c
将看到代码后面提供的位置参数。例如这个
gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' zeroth first second …
将打印remember: first
.
当代码最终解释时,在代码后不提供任何内容会导致$1
(或$2
等$3
)扩展为空字符串($0
有些不同,但这在这里并不重要)。这就是你得到的原因remember:
。/bin/sh
run bygnome-terminal
对主脚本的位置参数一无所知,除非您显式传递它们。
解决方案
要使用脚本的位置参数填充内部代码的位置参数,请使用"$@"
而不是first second …
:
gnome-terminal -- /bin/sh -c 'echo "remember: $1"; exec bash' sh "$@"
你可以通过任何你想要的。这里我们传递所有参数("$@"
扩展到所有位置参数),但一般来说你可以使用"$1"
(如果你想让内部代码知道第一个参数仅有的) 或"$2"
(如果您希望内部代码看到第二主脚本的位置参数为它自己的 $1
)。
笔记
sh
第零个参数的解释如下:中的第二个 sh 是什么sh -c 'some shell code' sh
?如果在您的原始脚本中(即没有我的修复),您打算提供的 shell 代码
sh -c
是双引号的,那么 shell 解释的脚本将扩展$1
并将结果嵌入到内部代码中。但不要这样做。# 有缺陷的
gnome-terminal -- /bin/sh -c "echo 'remember: $1'; exec bash"在许多情况下,这会如您所期望的那样工作;但不是一般情况下。一般来说,它的缺陷如下嵌入
{}
。单引号代码和后面的参数是正确的方法。单引号代码可确保其
/bin/sh -c
按原样 (内部双引号并不重要)。然后sh
会看到代码为echo "remember: $1"; exec bash
和双引号很好
$1
这里。