无法打印脚本中的位置参数

无法打印脚本中的位置参数

我在用着这个方法打开 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/shrun 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这里。

相关内容