为什么在 sh 和 bash 的情况下我会得到不同的输出?

ris*_*iag 8 command-line bash

我有以下简单的脚本:

#!/bin/bash
echo "Bash version ${BASH_VERSION}..."
for i in {1..99..2}
do
        echo $i
done
Run Code Online (Sandbox Code Playgroud)

如果我运行,输出sh file.sh

Bash version ...
{1..99..2}
Run Code Online (Sandbox Code Playgroud)

如果我运行,输出bash file.sh

Bash version 4.2.25(1)-release...
1
3
5
.
.
.
99
Run Code Online (Sandbox Code Playgroud)

我有两个疑问:

  1. 如果我写了一个shabang行指定的外壳,不应该将其与运行bash的我无论是使用sh file.sh还是bash file.sh

  2. 我知道$BASH_VERSIONsh 无法识别,但是 for 循环有什么问题?为什么不打印数字?

mur*_*uru 16

sh,Bourne shell 是旧的。它的行为由POSIX 标准指定。如果你想要新的行为,你可以使用bashBourne Again shell,它会一直添加新功能。在许多系统上,sh只是bash,并bash在以该名称运行时打开兼容模式。在 Ubuntu 上,shdashDebian Almquist shell。

大括号扩展是一个相对较新的特性,并且在旧的 bash 中也不可用。它当然不应该在sh.

仅当您将脚本作为可执行文件调用时,才尊重 shebang 行:

./myscript.sh
Run Code Online (Sandbox Code Playgroud)

我可以给一个脚本任何 shebang 并且仍然通过运行在 Python 中打开它:

python myscript.sh
Run Code Online (Sandbox Code Playgroud)

请参阅有关 Unix 和 Linux 的这些优秀问题:


Kaz*_*lfe 5

SH是个傻子。它什么也做不了。

它只知道最基本的命令。它不做任何其他事情。

它不能将 {1..99} 理解为数值。它把它理解为一个字符串。

SH/Dash 未开发。它旨在作为 DIRE 情况的紧急提示(在交互模式下。否则,这对于脚本编写来说是一件非常好的事情。)。

推荐使用 Bash,因为它可以做 SH 所能做的一切,以及最新的定制和强大的功能。

回答#1,#!只有在直接调用程序时才会解析。(如,,./program.sh

  • “*它是针对 DIRE 情况的紧急提示。*” [`dash`](http://manpages.ubuntu.com/manpages/man1/dash.1.html),正如你所说的提供 `sh ` 在 Ubuntu 中,主要不是“作为 DIRE 情况的紧急提示”而是 [因此系统可以运行,并且*启动*,快速](https://wiki.ubuntu.com/DashAsBinSh)。通过这种方式,`dash` 非常适合在现代操作系统中使用,但它最适合*用于*的是作为用于脚本编写的低调、快速的外壳——尤其是在启动大型、复杂、现代操作系统,性能开销最小。 (6认同)
  • 昨天,检查命令的可移植性。但是您认为 dash 的交互式使用很少见的观点是有效的。(无论如何,我的交互式使用的上下文仍然是面向脚本的。)....但是“使用”并不意味着“交互式使用”,更重要的是,*这个问题中的用例不是交互式用例! * (2认同)