Linux中的shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和Korn shell(ksh)。三种shell各有优缺点。Bourne shell是UNIX最初使用的shell,并且在每种UNIX上都可以使用。Bourne shell在shell编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。Linux操作系统缺省的shell是Bourne Again shell,它是Bourne shell的扩展,简称Bash,与Bourne shell完全向后兼容,并且在Bourne shell的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了很多C shell和Korn shell中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。
但是,在我们的linux系统中,sh是bash的一个软链接:
那为什么上面的例子中还会出现问题呢?原因在于:
bash程序执行,当“$0”是“sh”的时候,
则要求下面的代码遵循一定的规范,当不符合规范的语法存在时,则会报错,
所以可以这样理解,
“sh”并不是一个程序,而是一种标准(POSIX),
这种标准,在一定程度上(具体区别见下面的“Things bash has that sh does not”)保证了脚本的跨系统性(跨UNIX系统)
下面的内容详细的说明了bash与sh在语法等方面的具体差异(引自Bash FAQ):
2、调用相关:
在脚本的调用方面(interactive、login相关),bash与sh也是存在差异
以下是详细说明(假如被调用执行的脚本名字叫xxx.sh)
由此可以看出,最主要的区别在于相关配置文件的是否载入,
而这些配置的是否载入,也就导致了很多默认选项的差异
(具体请仔细查看~/.bash_profile 等文件)
如:
即,如果/etc/profile没有被载入,则不会产生core dump
3、关于ssh
非常值得一提的是,使用ssh远程执行命令,
远端sshd进程通过“bash –c”的方式来执行命令(即“非交互式的非登录shell”)
所以这一点,和登录之后再在本地执行执行命令,就存在了一定的差异
如:
注:
“$-” 中含有“i”代表“交互式shell”
“$0”的显示结果为“-bash”,bash前面多个“-”,代表“登录shell”
没有“i“和“-”的,是“非交互式的非登录shell”
另外还有一点,虽然ssh远程执行的命令是“非交互式的非登录shell”,
但在执行命令之前,ssh的那一次登录本身是“交互式的登录shell”,所以其会先载入“~/.bash_profile”
如:
这一点,衍生出一个关于scp的问题,scp在传输数据之前,会先进行一次ssh登录,
而当.bashrc文件有输出的时候,则会导致scp失败!原因是解析返回的数据包出现混乱
如:
GNU/Linux 操作系统中的 /bin/sh 是 bash(Bourne-Again Shell)的符号链接,但鉴于 bash 过于复杂,有人把 ash 从 NetBSD 移植到 Linux 并更名为 dash(Debian Almquist Shell),并建议将 /bin/sh 指向它,以获得更快的脚本执行速度。Ubuntu 号称自从他们在 6.10 版里这样做了以后,系统启动速度有了明显的提升。Debian 计划在下一个发行版(代号 lenny)中也将 dash 作为默认的 /bin/sh。
1、bash的POSIX标准
在一般的linux系统当中(如redhat),
使用sh调用执行脚本相当于打开了bash的POSIX标准模式
(等效于bash的 --posix 参数)
一般的,sh是bash的“子集”
(不是子集的部分,具体区别见下的“Things sh has that bash does not”)
例子:
但是,在我们的linux系统中,sh是bash的一个软链接:
那为什么上面的例子中还会出现问题呢?原因在于:
bash程序执行,当“$0”是“sh”的时候,
则要求下面的代码遵循一定的规范,当不符合规范的语法存在时,则会报错,
所以可以这样理解,
“sh”并不是一个程序,而是一种标准(POSIX),
这种标准,在一定程度上(具体区别见下面的“Things bash has that sh does not”)保证了脚本的跨系统性(跨UNIX系统)
下面的内容详细的说明了bash与sh在语法等方面的具体差异(引自Bash FAQ):
2、调用相关:
在脚本的调用方面(interactive、login相关),bash与sh也是存在差异
以下是详细说明(假如被调用执行的脚本名字叫xxx.sh)
由此可以看出,最主要的区别在于相关配置文件的是否载入,
而这些配置的是否载入,也就导致了很多默认选项的差异
(具体请仔细查看~/.bash_profile 等文件)
如:
即,如果/etc/profile没有被载入,则不会产生core dump
3、关于ssh
非常值得一提的是,使用ssh远程执行命令,
远端sshd进程通过“bash –c”的方式来执行命令(即“非交互式的非登录shell”)
所以这一点,和登录之后再在本地执行执行命令,就存在了一定的差异
如:
注:
“$-” 中含有“i”代表“交互式shell”
“$0”的显示结果为“-bash”,bash前面多个“-”,代表“登录shell”
没有“i“和“-”的,是“非交互式的非登录shell”
另外还有一点,虽然ssh远程执行的命令是“非交互式的非登录shell”,
但在执行命令之前,ssh的那一次登录本身是“交互式的登录shell”,所以其会先载入“~/.bash_profile”
如:
这一点,衍生出一个关于scp的问题,scp在传输数据之前,会先进行一次ssh登录,
而当.bashrc文件有输出的时候,则会导致scp失败!原因是解析返回的数据包出现混乱
如: