【问题标题】:Strange script behaviour when shebang references different shell当shebang引用不同的shell时奇怪的脚本行为
【发布时间】:2012-09-05 13:04:21
【问题描述】:

我最近切换到 ksh93 shell。我通过在我的 .profile 文件中添加以下两行来做到这一点

export SHELL=/usr/local/bin/ksh93
exec $SHELL

自从我这样做后,一些简单的脚本开始以我不理解的方式出现异常。我将其缩小到以下简单的脚本,称为 say test.sh

#!/bin/ksh
echo $0 $1

如果我输入命令test.sh fred,我希望看到相同的输出test.sh fred。相反,我看到test.sh noglob。如果我删除 shebang 或将其更改为 #!/usr/local/bin/ksh93,则脚本将按预期工作。

谁能解释发生了什么,或者该怎么做?我被难住了。

如果有什么不同的话,我使用的是 Solaris 5.9。

【问题讨论】:

  • /bin/ksh 中有什么内容?大概是一个 shell 脚本,它以某种方式替换了 $1 的值,可能是出于粗心。
  • @tripleee /bin/ksh 是 korn shell(我在切换到 ksh93 之前使用的那个)
  • 嗯,那一大堆命令可能值得进一步研究。
  • 在 Solaris 上,/bin/ksh 是(默认情况下)ksh 的实际可执行文件。不支持 --version 只是表明它是一个真实的(并且可能是旧的)Korn shell。
  • 听起来好像ksh 启动文件中的某些东西正在破坏传递给脚本的选项,可能使用set -- noglob,但更可能使用更微妙的机制(但set 可能数据)。仔细查看echo之前的所有命令。

标签: shell unix solaris ksh shebang


【解决方案1】:

我从 cmets 注意到您的 .kshrc 有一个 set noglob。没有选项的set 命令将设置命令行参数,这就是为什么$1 是“noglob”,它应该是set -o noglob

顺便说一句,设置noglob 很奇怪,你确定要那样吗?

我怀疑(正如其他人提到的)/bin/ksh 是 Korn shell 88。
关于.kshrc,ksh88 和 ksh93 之间有一个重要区别。在 ksh88 上,.kshrc 为每个 korn shell 进程执行,甚至是非交互式进程(脚本)。在 ksh93 中,.kshrc为 shell 脚本执行,仅用于交互式登录 shell。

当您执行exec $SHELL 不是登录shell 时,最好更改您在/etc/passwd 中的条目。顺便说一句,使用变量 SHELL 是个坏主意,因为它是由登录 shell 设置的。

【讨论】:

  • 感谢 cmets。我知道你提出的大部分问题。不幸的是,更改 /etc/passwd 对我来说是不切实际的,涉及的官僚机构太多。设置 noglob 是因为我遵循这些说明 mkssoftware.com/docs/man1/resize.1.asp 却没有意识到它们适用于 C shell。我现在已经解决了。
  • 在 Solaris 10 进行到一半时,ksh88sun$ENV 相关的行为已在更新/补丁中得到修复。在此之前,脚本以#!/bin/ksh -p 开头以防止在脚本中使用$ENV 是很常见的。 (-p 选项不过是一种解决方法)
【解决方案2】:

您的系统中的 ksh 上可能有一个别名,其中 noglob 设置为选项,或者在您的旧 shell 中默认情况下 noglob 作为默认参数传递。您还应该检查您真正调用的 ksh(检查 /bin/ksh 中是否有指向另一个 shell 的链接)。 ksh --version 也应该提供一些见解。

最后一点,我建议不要直接调用 shell

 #!/usr/bin/env ksh

【讨论】:

  • 我没有 ksh 的别名,/bin/ksh 也不是任何东西的链接。 ksh -version 只是给出一个错误-version: bad option(s)。我不明白关于默认参数的一点。使用#!/usr/bin/env ksh 没有区别。
  • 对不起,这是 ksh --version。 #!/usr/bin/env PROGRAM 是您应该遵循的一般规则,因为它使您的脚本(稍微多一点)独立于系统。如果您尝试 ksh -o 您将看到所有 ksh shell 选项(glob/noglob 就是其中之一)。版本号应该能让您更深入地了解这种奇怪的行为。
  • ksh --version 不产生任何输出,ksh -o 表示关闭 noglob。
  • ksh --version 不受 ksh88 支持,这是与 Solaris 一起使用的,--version 是 ksh93 功能。一种解决方法是strings /bin/ksh | grep Version。 @count0,请不要建议将 /bin/ksh 链接到其他东西。 ksh 是核心 Solaris 的一部分。替换它可能会破坏现有脚本并使系统不受支持。
  • 我已删除该建议。没有想到依赖于 ksh88 的 solaris 特定系统脚本。大多数 linux 发行版将重要的系统工具链接到 /etc/defaults 以允许自定义该行为。我从来没有遇到没有 --version 支持的 ksh(在许多系统上),这毕竟是一个令人惊讶的事实。而 88 版到现在已经 24 岁了,算是个化石了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多