在编写shell程序时,我们经常使用/bin/sh
和/bin/bash
。我通常使用bash
,但我不知道它们之间有什么区别。
bash'和
sh'的主要区别是什么?
用bash
和sh
编程时,我们需要注意什么?
sh
(或称Shell命令语言)是一种由POSIX
标准。
它有许多实现(ksh88
, dash
, ...)。bash
也可以被认为是
bash
也可以被认为是sh
的一个实现(见下文)。
因为sh
是一个规范,而不是一个实现,/bin/sh
是一个符号链接
(或硬链接) 到大多数POSIX系统上的实际实现。
bash
开始是一个与sh
兼容的实现(尽管它比POSIX标准早了几年), 但随着时间的推移, 它已经获得了许多扩展.许多这些扩展可能会改变有效的POSIX shell脚本的行为,所以本身bash
不是一个有效的POSIX shell。相反,它是POSIX shell语言的一种方言。
bash
支持一个--posix
开关,这使得它更符合POSIX标准。如果作为sh
调用,它也会尝试模仿POSIX。
很长时间以来,在大多数GNU/Linux系统中,/bin/sh
都是指向/bin/bash
。因此,忽略这两者之间的区别几乎已经变得安全了。但是,这种情况最近开始发生变化。
一些流行的例子是/bin/sh
不指向/bin/bash
的系统(在一些系统中/bin/bash
甚至可能不存在)。
1.现代的Debian和Ubuntu系统,默认将sh
链接到dash
。
2.Busybox,它通常在Linux系统启动时作为initramfs
的一部分运行。它使用ash
外壳实现。
3.3. BSDs,以及一般的任何非Linux系统。OpenBSD使用pdksh
,是Korn shell的后裔。FreeBSD的sh
是原始UNIX Bourne shell的后裔。 Solaris有自己的sh
,在很长一段时间里,它不符合POSIX标准;[Heirloom项目](http://heirloom.sourceforge.net/sh.html)提供了一个免费的实现。
你怎么能知道你的系统中/bin/sh
指向什么?
复杂的是,/bin/sh
可能是一个符号链接或一个硬链接。
如果它是一个符号链接,一个portable的方法来解决它:。
% 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
是一种非常简约的编程语言。
sh
: http://man.cx/sh
bash
: http://man.cx/bash
TL;DR:bash
是sh
的超集,语法更优雅,功能更多。几乎在所有情况下使用bash shebang行都是安全的,因为它在现代平台上是非常普遍的。
注意:在某些环境中,sh
是*bash
。检查sh -- 版本
。
Shell是用户和操作系统之间的一个接口,用于访问操作系统的服务。它可以是GUI或CLI(命令行界面)。
sh(Bourne shell)是一个shell命令行解释器,用于Unix/Unix-like操作系统。它提供了一些内置的命令。在脚本语言中,我们把解释器表示为#!/bin/sh
。它是其他shells最广泛支持的一种,如bash(免费/开放)、kash(非免费)。
Bash(Bourne again shell)是Bourne shell的替代品。Bash是sh的超集。Bash支持sh。POSIX是一套标准,定义了符合POSIX的系统应该如何工作。 Bash实际上不是一个符合POSIX的shell。在脚本语言中,我们把解释器表示为#!/bin/bash
。
类比: