#!/bin/sh 之后的破折号'-' -

Posted

技术标签:

【中文标题】#!/bin/sh 之后的破折号\'-\' -【英文标题】:dash '-' after #!/bin/sh -#!/bin/sh 之后的破折号'-' - 【发布时间】:2019-11-28 15:59:02 【问题描述】:

我一直在 CentOS 7 上编写一些脚本,有时我会看到:

#!/bin/sh -

在第一行。查看sh 的手册页我在Special Parameters 下看到以下内容

   -      Expands to the current option flags as  specified  upon  invocation,
          by  the  set  builtin  command, or those set by the shell
          itself (such as the -i option).

这到底是什么意思?我什么时候需要使用这个特殊的参数选项??

【问题讨论】:

如果您询问有关/bin/sh 的问题,请标记他们sh,而不是bash。即使您的sh 由 bash 实现的,它在以该名称启动时也在兼容模式下运行。 我删除了bash标签并用sh替换它 这是一个很好的问题,我在看书的时候也有同样的问题。接受的答案解决了我的问题。为了证明这一点,我已经尝试过:创建一个名为-c 的文件,第一行为#!/usr/bin/sh,更改路径:PATH=.,这样我就可以以-c 而不是./-c 运行该文件。运行文件:-c,命令-c 变为/usr/bin/sh -c。因为-csh的一个选项,所以输出为:/usr/bin/sh: -c: option requires an argument。在此之后我将第一行更改为#!/usr/bin/sh -,并且输出什么都没有,意味着它运行正确(/usr/bin/sh - -c-c 被视为文件)。 【参考方案1】:

您正在阅读的文档与您正在查看的命令行无关:它指的是特殊变量。在这种情况下,如果您运行echo $-,您将看到“调用时指定的当前选项标志...”。

如果您查看bash 手册页的OPTIONS 部分,您会发现:

--       A -- signals the end of options and disables  further  option  processing.
         Any  arguments  after  the  -- are treated as filenames and arguments.  An
         argument of - is equivalent to --.

换句话说,- 的参数仅表示“在此参数之后没有其他选项”。

您经常会看到这种情况下,您希望避免以- 开头的文件名意外地被视为命令选项:例如,如果当前目录中有一个名为-R 的文件,则运行ls *实际上将表现为ls -R 并产生递归列表,而ls -- * 不会特别处理-R 文件。

#! 行中使用的单破折号表示安全预防措施。你可以阅读更多关于here的信息。

【讨论】:

【参考方案2】:

/bin/sh 是代表系统外壳的可执行文件。实际上,它通常被实现为指向可执行文件的符号链接,无论哪个 shell 是系统 shell。系统 shell 是系统脚本应该使用的默认 shell。在 Linux 发行版中,很长一段时间以来,这通常是指向 bash 的符号链接,以至于总是将 /bin/sh 链接到 bash 或与 bash 兼容的 shell 已成为一种惯例。 然而,在过去的几年里,Debian(和 Ubuntu)决定将系统 shell 从 bash 切换到 dash - 一个类似的 shell - 打破了 Linux(嗯,GNU)使用 bash 的悠久传统对于 /bin/sh。 Dash 被视为一种更轻、更快的 shell,它有助于提高启动速度(以及其他需要大量 shell 脚本的东西,例如包安装脚本)。

Dash 与 bash 相当兼容,基于相同的 POSIX 标准。但是,它没有实现特定于 bash 的扩展。存在使用 #!/bin/sh(系统 shell)作为它们的 shebang 的脚本,但需要特定于 bash 的扩展。这目前被认为是 Debian 和 Ubuntu 应该修复的错误,它们需要 /bin/sh 在指向破折号时才能工作。

即使 Ubuntu 的系统 shell 指向 dash,此时您作为用户的登录 shell 仍然是 bash。也就是说,当您在 Linux 中的任何位置登录到终端仿真器时,您的登录 shell 将是 bash。当以交互方式使用 shell 并且用户熟悉 bash(并且可能在他们的主目录中具有特定于 bash 的自定义)时,操作速度不是问题。

【讨论】:

在 CentOS 上,/bin/sh 指向 /bin/bash,所以我在 /bin/sh 之后的 - 是 bash 的参数。总之,我们的软件只能在 CentOS 上运行。 这并没有回答为什么有些脚本在 shebang 之后包含 - 的问题。

以上是关于#!/bin/sh 之后的破折号'-' -的主要内容,如果未能解决你的问题,请参考以下文章

在一个非常愚蠢的 shell 中添加/减去变量

/bin/sh: 1: ctags: not found

Shell 的基础知识

linux /bin/sh -c的用途

docker进入式 执行sh

在 C 中计算破折号以退出 While 循环