#!/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
。因为-c
是sh
的一个选项,所以输出为:/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 之后的破折号'-' -的主要内容,如果未能解决你的问题,请参考以下文章