美文网首页
Linux—/bin/sh、/bin/bash、/bin/das

Linux—/bin/sh、/bin/bash、/bin/das

作者: PC_Repair | 来源:发表于2021-11-20 23:47 被阅读0次

    bash

    bash 是一个为GNU计划编写的Unix shell。它的名字是一系列缩写:Bourne-Again SHell — 这是关于Bourne shell(sh)的一个双关语(Bourne again / born again)。Bourne shell是一个早期的重要shell,由史蒂夫·伯恩在1978年前后编写,并同Version 7 Unix一起发布。bash则在1987年由布莱恩·福克斯创造。

    bash (GNU Bourne-Again Shell) 是许多Linux发行版的默认Shell 。事实上,还有许多传统UNIX上用的Shell,例如tcsh、csh、ash、bsh、ksh等等,Shell Script大致都类同。
    由于历史原因,UNIX系统上有很多种Shell:

    • csh(C Shell):由Bill Joy开发,随BSD UNIX发布,它的流程控制语句很像C语言,支持很多Bourne Shell所不支持的功能:作业控制,命令历史,命令行编辑。

    • ksh(Korn Shell):由David Korn开发,向后兼容sh的功能,并且添加了csh引入的新功能,是目前很多UNIX系统标准配置的Shell,在这些系统上/bin/sh往往是指向/bin/ksh的符号链接。

    • tcsh(TENEX C Shell):是csh的增强版本,引入了命令补全等功能,在FreeBSD、Mac OS X等系统上替代了csh。

    • bash(Bourne Again Shell):由GNU开发的Shell,主要目标是与POSIX标准保持一致,同时兼顾对sh的兼容,bash从csh和ksh借鉴了很多功能,是各种Linux发行版标准配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash的符号链接。

    可使用cat /etc/shells 指令查看自己系统可以使用的shell种类:

    image-20211120231230430.png

    用户的默认 Shell 设置在/etc/passwd文件中,例如:vim /etc/passwd

    image-20211120231337573.png

    sh

    在 shell 脚本的开头往往有一句话来定义使用哪种 sh 解释器来解释脚本。
    目前常见的 shell 脚本中主要有以下两种方式:
    (1) #!/bin/sh
    (2) #!/bin/bash

    注意:每个脚本开头都使用"#!",#!实际上是一个2字节魔法数字,这是指定一个文件类型的特殊标记,在这种情况下,指的就是一个可执行的脚本。在#!之后,接一个路径名,这个路径名指定了一个解释脚本命令的程序,这个程序可以是shell,程序语言或者任意一个通用程序。
    sh是bash的一种特殊的模式,也就是 /bin/sh 相当于 /bin/bash --posix。说白了sh就是开启了POSIX标准的bash 。
    在一般的linux系统当中(如redhat),使用sh调用执行脚本相当于打开了bash的POSIX标准模式
    sh一般设成bash的软链:

    image-20211120231421597.png

    怎么把sh改为指向bash呢?

    • 方法一:直接把/bin/sh的软链接改到bash中,如:ln -s /bin/bash /bin/sh
    • 方法二:配置shell,sudo dpkg-reconfigure dash

    dash

    鉴于 bash 过于复杂,有人把 bash 从 NetBSD 移植到 Linux 并更名为 dash(Debian Almquist Shell),并以获得更快的脚本执行速度。Debian Almquist shell,缩写为dash,一种 Unix shell。它比 Bash 小,只需要较少的磁盘空间,但是它的对话性功能也较少。它由 NetBSD版本的Almquist shell (ash)发展而来,于1997年,由赫伯特·许(Herbert Xu)移植到Linux上,于2002年改名为 dash。

    ll -h /bin/
    

    那么怎么把 sh 改为指 dash 呢?

    sudo dpkg-reconfigure dash
    # 选择yes使用dash作为默认的shell即可修改为dash。
    

    #!/bin/bash是指此脚本使用 /bin/bash 来解释执行。其中,#!是一个特殊的表示符,其后,跟着解释此脚本的shell路径。
    bash 只是 shell 的一种,还有很多其它 shell,如:sh,csh,ksh,tcsh,…我们可以通过以下一个示例来进行实验,了解#!/bin/bash的使用。
    除第一行外,脚本中所有以“#”开头的行都是注释。
    1)#!/bin/bash只能放在第一行,如果后面还有#!,那么只能看成是注释。
    这里有三个脚本(脚本都要使用”chmod +x scriptname“命令来获得可执行权限):

    • tbash1.sh:
    #!/bin/sh
    source abc
    echo “hello abc”
    
    • tbash2.sh:
    #!/bin/bash
    source abc
    echo “hello abc”
    
    • tbash3.sh:
    source abc
    echo “hello abc”
    

    三个脚本执行的结果:

    [nsvc@localhost other]$ ./tbash1.sh
    ./tbash1.sh: line 2: abc: No such file or directory
    # 注:当source命令执行有问题时,sh不再往下面执行。
    
    [nsvc@localhost other]$ ./tbash2.sh
    ./tbash2.sh: line 2: abc: No such file or directory
    hello abc
    # 注:当source命令执行有问题时,bash继续执行下面命令。
    
    [nsvc@localhost other]$ ./tbash3.sh
    ./tbash3.sh: line 1: abc: No such file or directory
    hello abc
    # 注:自身登录系统所在的shell是bash。所以,当source命令执行有问题时,bash继续执行下面命令。
    

    如果将 tbash1.sh 改成:

    echo “abc”
    #!/bin/sh
    source abc
    echo “hello abc”
    

    那么,执行结果是:

    [nsvc@localhost other]$ ./tbash1.sh
    abc
    ./tbash1.sh: line 3: abc: No such file or directory
    hello abc
    # 也就是说,脚本忽略了第二行“#!/bin/sh",直接使用当前所在的shell(也就是bash)来解释脚本。
    

    当把 tbash1.sh 改成:

    #!/bin/sh
    #!/bin/bash
    source abc
    echo “hello abc”
    

    执行结果为:

    [nsvc@localhost other]$ ./tbash1.sh
    ./tbash1.sh: line 3: abc: No such file or directory
    # 当执行完source命令时,并没有往下执行。说明,#!/bin/sh这一行起到作用了,但#!/bin/bash并没有起作用。在脚本中,除第一行外,脚本中所有以“#”开头的行都是注释。
    

    2)#!后面的路径一定要正确,不正确会报错。
    假如,我们把tbash1.sh中第一行的#!后面加了一个不存在的路径”/home/sh“:

    #!/home/sh
    source abc
    echo “hello abc”
    

    执行结果为:

    [nsvc@localhost other]$ ./tbash1.sh
    -bash: ./tbash1.sh: /home/sh: bad interpreter: No such file ordirectory
    # 系统会提示/home/sh的路径不存在。
    

    3)如果一个脚本在第一行没有加上#!+shell路径这一行,那么,脚本会默认当前用户登录的shell,为脚本解释器。
    在1)中,脚本 tbash3.sh 的执行结果,就是用当前自己登录的shell(bash)解释后的结果。我们通常所用的shell都是bash,如果哪天登录到sh,再使用以上类型的脚本,就会有问题。以下是自己登录到sh下,执行tbash3.sh的结果:

    -sh-3.2$ ./tbash3.sh
    ./tbash3.sh: line 1: abc: 没有那个文件或目录
    

    与1)中的执行结果是不一样的。
    因此,大家应该养成脚本首行加上#!+shell路径的习惯。

    4)/bin/sh 相当于 /bin/bash --posix
    我们将脚本 tbash1.sh 改为:

    #!/bin/bash --posix
    source abc
    echo “hello abc”
    

    执行结果:

    [nsvc@localhost other]$ ./tbash1.sh
    ./tbash1.sh: line 2: abc: No such file or directory
    # 与tbash1.sh原脚本执行的结果一样。
    

    我们还可以以tbash3.sh为示例。
    用以下命令来执行该脚本:

    [nsvc@localhost other]$ bash tbash3.sh
    tbash3.sh: line 1: abc: No such file or directory
    hello abc
    
    [nsvc@localhost other]$ sh tbash3.sh
    tbash3.sh: line 1: abc: No such file or directory
    [nsvc@localhost other]$ bash --posix tbash3.sh
    tbash3.sh: line 1: abc: No such file or directory
    

    "bash tbash3.sh"表示使用bash来作为脚本解释器来执行tbash3.sh。同样,也可以使用如”sh脚本名“这样的命令,来用sh作为脚本解释器。
    从结果可以看出,/bin/bash–posix/bin/sh的执行结果相同。总结起来,sh跟bash的区别,实际上是bash有没开启posix模式的区别。遵守posix规范,可能包括,”当某行代码出错时,不继续往下执行。“

    最后加上一点说明,每个脚本开头都使用"#!",#!实际上是一个2字节魔法数字,这是指定一个文件类型的特殊标记,在这种情况下,指的就是一个可执行的脚本。在#!之后,接一个路径名,这个路径名指定了一个解释脚本命令的程序,这个程序可以是shell,程序语言或者任意一个通用程序。

    相关文章

      网友评论

          本文标题:Linux—/bin/sh、/bin/bash、/bin/das

          本文链接:https://www.haomeiwen.com/subject/rmcptrtx.html