在编写Shell程序时,我们经常使用/bin/sh
和/bin/bash
。我通常使用bash
,但是我不知道它们之间有什么区别。
bash
和之间的主要区别是sh
什么?
在bash
和中进行编程时,我们需要注意sh
什么?
在编写Shell程序时,我们经常使用/bin/sh
和/bin/bash
。我通常使用bash
,但是我不知道它们之间有什么区别。
bash
和之间的主要区别是sh
什么?
在bash
和中进行编程时,我们需要注意sh
什么?
Answers:
sh
(或Shell命令语言)是POSIX标准描述的一种编程语言。它有许多的实现(ksh88
,dash
,...)。bash
也可以视为的实现sh
(请参见下文)。
因为sh
是规范,而不是实现,所以它/bin/sh
是到大多数POSIX系统上实际实现的符号链接(或硬链接)。
bash
开始时是一个sh
兼容的实现(尽管它比POSIX标准早了几年),但是随着时间的流逝,它获得了许多扩展。这些扩展中的许多扩展名可能会更改有效POSIX Shell脚本的行为,因此,它本身bash
不是有效的POSIX Shell。相反,它是POSIX Shell语言的方言。
bash
支持一个--posix
开关,这使其更符合POSIX。如果以调用,它也会尝试模仿POSIX sh
。
长期以来,/bin/sh
它一直指向/bin/bash
大多数GNU / Linux系统。结果,几乎可以忽略两者之间的区别了。但是这种情况最近开始改变。
/bin/sh
不指向/bin/bash
(某些/bin/bash
甚至可能不存在)的系统的一些流行示例是:
sh
到dash
;initramfs
。它使用ash
shell实现。pdksh
Korn shell的后代。FreeBSD sh
是原始UNIX Bourne shell的后代。Solaris具有自己的sh
名称,长期以来不兼容POSIX。Heirloom项目提供了免费的实现。您如何找出/bin/sh
系统上的指向?
复杂之处在于它/bin/sh
可能是符号链接或硬链接。如果它是符号链接,则一种可解决的便携式方法是:
% file -h /bin/sh
/bin/sh: symbolic link to bash
如果是硬链接,请尝试
% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
实际上,该-L
标志涵盖了符号链接和硬链接,但是此方法的缺点是它不可移植-POSIX 不需要 find
支持该-samefile
选项,尽管GNU find和FreeBSD find都支持该选项。
最终,由您决定要使用哪个脚本,方法是将“ shebang”行写为脚本的第一行。
例如
#!/bin/sh
将使用sh
(以及碰到的任何东西),
#!/bin/bash
将/bin/bash
在可用的情况下使用(如果不可用,则会失败并显示错误消息)。当然,您也可以指定其他实现,例如
#!/bin/dash
对于我自己的脚本,sh
出于以下原因,我更喜欢:
bash
,也必须具有sh
使用也有好处bash
。它的功能使编程更加方便,并且类似于其他现代编程语言中的编程。这些包括范围局部变量和数组之类的东西。Plain sh
是一种非常简约的编程语言。
bash
显示方式运行脚本,则在语法错误的情况下会显示更多有用的错误消息。您只需使用bash即可节省时间。
%
命令行开头是什么意思?
$
代替%
,或将其#
用作根外壳程序。
$
和#
...
sh
,bash之前就已经存在(代表bourne-again shell)。但这是非常原始的,并且不会响应终端事件,例如ESC
字符。然后ksh
来了(也就是在bash之前),然后bash由那些喜欢更好的shell但讨厌ksh的人开始。:-)
sh
:http
bash
: //man.cx/sh:http : //man.cx/bash
TL; DR:bash
是sh
具有更优雅的语法和更多功能的超集。在几乎所有情况下,使用bash shebang行都是安全的,因为它在现代平台上非常普遍。
注意:在某些环境中sh
是 bash
。检查sh --version
。
对于试图使用该问题的人,该问题经常被提名为规范问题sh
,但对此感到惊讶的是,它的行为与相同bash
。这是常见误解和陷阱的快速清单。
首先,您应该了解期望。
sh scriptname
,或运行它scriptname
,并有#!/bin/sh
在家当行,你应该期望POSIX sh
的行为。bash scriptname
,或者使用来运行脚本,scriptname
而#!/bin/bash
在shebang行中使用(或等效于本地的)脚本,则应该期望Bash行为。通常,首选解决方案是使用正确的shebang并通过仅键入脚本名称(可能使用相对路径或完整路径)来运行脚本。除了正确的Shebang之外,这还要求脚本文件具有执行权限(chmod a+x scriptname
)。
那么,它们实际上有何不同?
《 Bash参考手册》的一部分试图枚举差异,但一些常见的混淆源包括
[[
不可用sh
(仅[
笨重且受限)。sh
没有数组。local
,source
,function
,shopt
,let
,declare
,和select
无法移植到sh
。(某些sh
实现支持local
。)for((i=0;i<=3;i++))
循环,+=
增量分配等。该$'string\nwith\tC\aescapes'
功能暂时被POSIX接受(这意味着该功能现在在Bash中有效,但sh
仅遵循当前规范的系统尚不支持该功能。 POSIX规范,并且很可能在一段时间内不会发布)。<<<'here strings'
。*.{png,jpg}
和{0..12}
支撑扩张。~
$HOME
仅在Bash中引用(更普遍~username
地是指的主目录username
)。/bin/sh
实现中可能会丢失。<(cmd)
和替换进程>(cmd)
。&|
for 2>&1 |
和&>
for> ... 2>&1
<>
重定向的协同进程。${substring:1:2}
,${variable/pattern/replacement}
,大小写转换等$[expression]
语法,但是应替换为POSIX算术$((expression))
语法。(不过,某些旧的POSIX之前的sh
实现可能不支持此功能。)$RANDOM
,$SECONDS
,$PIPESTATUS[@]
和$FUNCNAME
是Bash的扩展。export variable=value
和一样的语法差异[ "x" == "y" ]
不可移植(export variable
应与变量赋值分开,并且可移植字符串比较[ ... ]
使用单个等号)。请记住,这是一个简短的清单。有关完整的信息,请参考参考手册;有关许多好的解决方法,请参见http://mywiki.wooledge.org/Bashism。和/或尝试http://shellcheck.net/,它会警告许多仅Bash功能。
一个常见的错误是有一个#!/bin/bash
shebang行,但是仍然使用它sh scriptname
来实际运行脚本。这基本上会禁用任何仅Bash的功能,因此会出现语法错误,例如,尝试使用数组。(shebang行在语法上是注释,因此在这种情况下,它只是被忽略。)
不幸的是,当您尝试以Bash调用这些构造时,Bash不会发出警告sh
。它也不会完全禁用所有仅Bash的功能,因此,通过调用它来运行Bash sh
并不是检查脚本是否可正确移植到ash
/ dash
/ POSIX sh
或Heirloom等变体的好方法sh
export variable=value
由POSIX强制授权:pubs.opengroup.org/onlinepubs/009695399/utilities/export.html。也许它在某些古老的外壳中不可用,但绝对不是bashism。
Shell是用户和OS之间的接口,用于访问操作系统的服务。它可以是GUI或CLI(命令行界面)。
sh(Bourne sh ell)是一个Shell命令行解释器,用于类似Unix / Unix的操作系统。它提供了一些内置命令。在脚本语言中,我们将解释器表示为#!/bin/sh
。它是bash(自由/开放),kash(非自由)之类的其他shell支持最广泛的一种。
击(乙 ourne 一个增益小号地狱)是一个外壳更换对于Bourne壳。Bash是sh的超集。Bash支持sh。POSIX是一组定义POSIX兼容系统应如何工作的标准。Bash实际上不是POSIX兼容的外壳。在脚本语言中,我们将解释器表示为#!/bin/bash
。
比喻:
sh
(因此,它是OOP的“子类”)并对其进行扩展(因此具有功能的超集)。
外壳功能
下表列出了我认为会让您选择一个外壳而不是另一个外壳的大多数功能。它不打算作为权威列表,也不包括每个可能的shell的每个可能的功能。仅当功能在操作系统随附的版本中,或者可以从标准发行版直接编译得到时,才认为该功能在外壳程序中。特别是,下面指定的C shell是SUNOS 4. *上可用的,现在许多供应商都提供tcsh或他们自己的增强型C shell(它们并不总是很明显地表明他们在交付tcsh。
码:
sh csh ksh bash tcsh zsh rc es
Job control N Y Y Y Y Y N N
Aliases N Y Y Y Y Y N N
Shell functions Y(1) N Y Y N Y Y Y
"Sensible" Input/Output redirection Y N Y Y N Y Y Y
Directory stack N Y Y Y Y Y F F
Command history N Y Y Y Y Y L L
Command line editing N N Y Y Y Y L L
Vi Command line editing N N Y Y Y(3) Y L L
Emacs Command line editing N N Y Y Y Y L L
Rebindable Command line editing N N N Y Y Y L L
User name look up N Y Y Y Y Y L L
Login/Logout watching N N N N Y Y F F
Filename completion N Y(1) Y Y Y Y L L
Username completion N Y(2) Y Y Y Y L L
Hostname completion N Y(2) Y Y Y Y L L
History completion N N N Y Y Y L L
Fully programmable Completion N N N N Y Y N N
Mh Mailbox completion N N N N(4) N(6) N(6) N N
Co Processes N N Y N N Y N N
Builtin artithmetic evaluation N Y Y Y Y Y N N
Can follow symbolic links invisibly N N Y Y Y Y N N
Periodic command execution N N N N Y Y N N
Custom Prompt (easily) N N Y Y Y Y Y Y
Sun Keyboard Hack N N N N N Y N N
Spelling Correction N N N N Y Y N N
Process Substitution N N N Y(2) N Y Y Y
Underlying Syntax sh csh sh sh csh sh rc rc
Freely Available N N N(5) Y Y Y Y Y
Checks Mailbox N Y Y Y Y Y F F
Tty Sanity Checking N N N N Y Y N N
Can cope with large argument lists Y N Y Y Y Y Y Y
Has non-interactive startup file N Y Y(7) Y(7) Y Y N N
Has non-login startup file N Y Y(7) Y Y Y N N
Can avoid user startup files N Y N Y N Y Y Y
Can specify startup file N N Y Y N N N N
Low level command redefinition N N N N N N N Y
Has anonymous functions N N N N N N Y Y
List Variables N Y Y N Y Y Y Y
Full signal trap handling Y N Y Y N Y Y Y
File no clobber ability N Y Y Y Y Y N F
Local variables N N Y Y N Y Y Y
Lexically scoped variables N N N N N N N Y
Exceptions N N N N N N N Y
上表的关键字。
可以使用此shell完成功能。
N功能不存在于外壳中。
F功能只能通过使用shell函数机制来完成。
L必须将readline库链接到外壳中才能启用此功能。
上表说明
1. This feature was not in the original version, but has since become
almost standard.
2. This feature is fairly new and so is often not found on many
versions of the shell, it is gradually making its way into
standard distribution.
3. The Vi emulation of this shell is thought by many to be
incomplete.
4. This feature is not standard but unofficial patches exist to
perform this.
5. A version called 'pdksh' is freely available, but does not have
the full functionality of the AT&T version.
6. This can be done via the shells programmable completion mechanism.
7. Only by specifying a file via the ENV environment variable.
终奌站
贝壳
相对于 重击
SH
重击
参考资料:
外壳 gnu.org:
从根本上说,外壳程序只是执行命令的宏处理器。术语宏处理器是指将文本和符号扩展以创建更大的表达式的功能。
Unix shell既是命令解释器又是编程语言。 作为命令解释器,shell为丰富的GNU实用程序集提供了用户界面。编程语言功能允许组合这些实用程序。包含命令的文件可以创建,也可以成为命令本身。这些新命令与/ bin等目录中的系统命令具有相同的状态,从而允许用户或组建立自定义环境以自动化其常见任务。
外壳可以交互使用或非交互使用。在交互模式下,它们接受键盘输入的输入。当以非交互方式执行时,shell执行从文件读取的命令。
Shell允许同步和异步执行GNU命令。在接受更多输入之前,shell等待同步命令完成。异步命令继续与外壳程序并行执行,同时读取并执行其他命令。重定向结构允许对这些命令的输入和输出进行细粒度的控制。而且,外壳程序允许控制命令环境的内容。
Shell还提供了一小组内置命令(builtins),这些命令实现了无法或不方便通过单独的实用程序获得的功能。例如,cd,break,continue和exec不能在Shell外部实现,因为它们直接操纵Shell本身。历史记录,getopts,kill或pwd内置程序等可以在单独的实用程序中实现,但用作内置命令更方便。后续各节将介绍所有的shell内置程序。
尽管执行命令是必不可少的,但是大多数Shell的功能(和复杂性)都归功于它们的嵌入式编程语言。 像任何高级语言一样,shell提供变量,流控制构造,引用和函数。
Shell提供了专门为交互使用而设计的功能,而不是扩展编程语言。这些交互式功能包括作业控制,命令行编辑,命令历史记录和别名。这些功能中的每一个都在本手册中进行了描述。
BASH gnu.org:
Bash是GNU操作系统的外壳程序或命令语言解释器。该名称是'Bourne-Again SHell'的首字母缩写,它是Stephen Bourne的双关语,Stephen Bourne是当前Unix shell sh的直接祖先的作者,该版本出现在Unix的第七版Bell Labs Research版本中。
Bash在很大程度上与sh兼容,并结合了Korn shell ksh和C shell csh的有用功能。它旨在成为IEEE POSIX规范(IEEE标准1003.1)的IEEE POSIX外壳和工具部分的一致实现。它提供了相对于sh的功能改进,可用于交互和编程。
虽然GNU操作系统提供了其他shell,包括csh版本,但Bash是默认的shell。像其他GNU软件一样,Bash具有很好的可移植性。目前,它几乎可以在Unix的每个版本以及其他一些操作系统上运行-MS-DOS,OS / 2和Windows平台存在独立支持的端口。
其他答案通常指出Bash与POSIX Shell标准之间的区别。但是,在编写可移植的shell脚本并使用Bash语法时,非常典型的bashism列表和相应的纯POSIX解决方案非常方便。当Ubuntu从Bash切换为Dash作为默认系统外壳时,已经编译了此类列表,可以在以下位置找到:https : //wiki.ubuntu.com/DashAsBinSh
此外,有一个很棒的工具叫做checkbashisms,它可以检查脚本中的bashisms,并在您要确保脚本可移植时很方便。
它们几乎相同,但bash
具有更多功能 – sh
是(或多或少)是的较旧子集bash
。
sh
通常是指Bourne shell
始于bash
(Bourne *again* shell
)并于1977年创建的原始文档。但是,在实践中,最好将其视为与1992年的POSIX标准兼容的高度交叉兼容的外壳。
#!/bin/sh
以sh
Shell 开头或使用Shell的脚本通常这样做是为了向后兼容。任何unix / linux操作系统都将具有sh
外壳。在Ubuntu上sh
经常调用dash
,在MacOS上是POSIX的特殊版本bash
。对于标准兼容的行为,速度或向后兼容性,这些外壳可能是首选。
bash
比原始版本更新sh
,添加了更多功能,并试图向后兼容sh
。理论上,sh
程序应在中运行bash
。 bash
在几乎所有的linux / unix计算机上都可用,并且通常默认情况下使用-值得注意的是MacOS默认zsh
为Catalina(10.15)。默认情况下,FreeBSD没有bash
安装。
sh
早于POSIX。这些天,您希望所sh
找到的至少与POSIX兼容;但是在旧系统上,这绝不是给定的。POSIX的标准化远不止于shell。实际上,您可能会说操作系统调用和库函数的标准化更为重要。
/bin/sh
可能会或可能不会调用与相同的程序/bin/bash
。
sh
至少支持POSIX所需的功能(假设实现正确)。它也可能支持扩展。
bash
,“ Bourne Again Shell”实现了sh以及bash特定的扩展所必需的功能。完整的扩展程序集太长,无法在此处描述,并且随新版本的发布而变化。差异记录在bash手册中。输入info bash
并阅读“ Bash功能”部分(当前版本中的第6部分),或者在线阅读当前文档。
sh
如果您PATH
在当前shell中进行了正确的设置,则只会为您提供POSIX shell。没有为您提供POSIX Shell的已定义PATH名称。
sh
都没有给您POSIX shell的必要。
bash和sh是两个不同的shell。bash基本上是sh,具有更多功能和更好的语法。大多数命令的工作原理是相同的,但它们是不同的。Bash(bash)是许多可用的(至今仍是最常用的)Unix shell之一。Bash代表“ Bourne Again SHell”,并且是对原始Bourne shell(sh)的替换/改进。
Shell脚本是在任何Shell中编写脚本,而Bash脚本是专门为Bash编写脚本。但是,实际上,除非有问题的shell不是Bash,否则“ shell脚本”和“ bash脚本”通常可以互换使用。
话虽如此,您应该在大多数系统上意识到/ bin / sh是符号链接,并且不会调用sh。在Ubuntu中,/ bin / sh用于链接到bash,这是Linux发行版上的典型行为,但现在已更改为链接到另一个称为dash的shell。我会使用bash,因为这几乎是标准的(或者至少从我的经验来看是最常见的)。实际上,当bash脚本将使用#!/ bin / sh时会出现问题,因为脚本创建者认为链接不一定是bash。
尽可能地做到以下 几点:基本了解之后,上面发布的其他评论将更容易理解。
Shell- “ Shell”是一个程序,可促进用户与操作系统(内核)之间的交互。有许多shell实现可用,例如sh,bash,csh,zsh ...等。
使用任何Shell程序,我们将能够执行该Shell程序支持的命令。
巴什 -它来源于乙 ourne- 一个增益嘘 ELL。使用此程序,我们将能够执行Shell指定的所有命令。另外,我们将能够执行一些专门添加到该程序中的命令。Bash与sh具有向后兼容性。
嘘-从伯恩衍生嘘埃尔。“ sh”支持外壳程序中指定的所有命令。就是说,使用此程序,我们将能够执行Shell指定的所有命令。
欲了解更多信息,做到: - https://man.cx/sh - https://man.cx/bash
Linux操作系统提供了不同类型的Shell。尽管shell有许多共同的命令,但每种类型都有其独特的功能。让我们研究另一种最常用的外壳。
Sh shell:
Sh shell也称为Bourne Shell。Sh shell是1977年AT&T的Bell Labs的Stephen Bourne为Unix计算机开发的第一个shell。它包含许多脚本工具。
打击壳:
Bash shell代表Bourne Again Shell。Bash shell是大多数linux发行版中的默认shell,并替代Sh Shell(Sh shell也将在Bash shell中运行)。Bash Shell可以执行绝大多数Sh Shell脚本,而无需进行修改,并且还提供命令行编辑功能。