关于#!/bin/bash和#!/bin/sh

 
#!/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,程序语言或者任意一个通用程序。

关于#!/bin/bash和#!/bin/sh的更多相关文章

  1. bin/bash 和 /bin/sh 的区别

    今天在用ssh Secure shell 连接虚拟机中的Ubuntu编写程序时,想比对一下两个源代码有什么差别,但是在一个ssh 客户端下不断的切换很是费劲.于是想着在主机中再添加一个用户.我原本用s ...

  2. Linux:/bin/bash和/bin/sh的区别

    bash.dash(/bin/bash和/bin/sh) 原文:http://www.cnblogs.com/dkblog/archive/2011/04/02/2003822.html Linux中 ...

  3. [shell]Linux脚本开头#!/bin/bash和#!/bin/sh是什么意思以及区别

    一直以为在shell脚本中#都是代表着注释功能,同样在脚本开始的#!/bin/sh也只是告诉用户这是一个shell脚本,而最近顺手查了下,才发现不是这个意思,分享下面的文章. 转自:http://ww ...

  4. Linux脚本开头#!/bin/bash和#!/bin/sh是什么意思以及区别

    一.意思 #!/bin/sh是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面根的是此解释此脚本的shell的路径. 其实第一句的#!是对脚本的解释器程序路径,脚本的内容是由解释器解释 ...

  5. 转 关于shell脚本中#!/bin/bash and #!/bin/ksh 的说明

      1.在文件里面输入一系列命令,可以直接执行吗? 可以.作者认为,这时调用的是当前用户默认使用的shell. 如果其中一个命令有错,后面的命令还是会继续执行下去的 如果说使用了”&& ...

  6. bash、dash(/bin/bash和/bin/sh)的区别

    Linux中的shell有多种类型,其中最常用的几种是Bourne   shell(sh).C   shell(csh)和Korn   shell(ksh).三种shell各有优缺点. Bourne ...

  7. Linux下#!/usr/bin/env bash和#!/usr/bin/bash、#!/bin/bash的比较

    #!/usr/bin/env bash #在不同的系统上提供了一些灵活性. #!/usr/bin/bash #将对给定的可执行文件系统进行显式控制. 通过/usr/bin/env运行程序,用户不需要去 ...

  8. alpine docker exec: "/bin/bash": stat /bin/bash: no such file or directory 解决方案

    sudo docker exec -it 1df4f9732e06 sh

  9. /bin/sh 与 /bin/bash 的区别

    /bin/sh 与 /bin/bash 的区别,用 : 截取字符串不是POSIX 标准的. 区别 sh 一般设成 bash 的软链 (symlink) ls -l /bin/sh lrwxrwxrwx ...

随机推荐

  1. Javascript面向对象编程:非构造函数的继承

    今天是最后一个部分,介绍不使用构造函数实现"继承". 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Ch ...

  2. java解析html的table

    import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org. ...

  3. Android补间动画、帧动画和属性动画使用知识介绍

    https://blog.csdn.net/zhangqunshuai/article/details/81098062

  4. update + join 多表操作

    UPDATE vtiger_notificationcf as a INNER JOIN vtiger_crmentity as b ON a.notificationid = b.crmid SET ...

  5. [arc066f]Contest with Drinks Hard

    题目大意: 有一些物品,每个买了有代价. 如果存在一个极大区间[l,r]内的物品都被买了,这个区间长度为k,可以获得的收益是k*(k+1)/2. 现在若干次询问,每次问假如修改了某个物品的价格,最大收 ...

  6. 做生活的有心人——xxx系统第一阶段总结

    2017秋,桃子已经步入大学三年级了,觉得格外幸运 因为现在,有了学习的动力. 如果你和我一样也是在大学中后部分才意识到,自己是个大人了,思维模式开始转变开始融入一些前所未有的认知,觉得自己渺小得如沧 ...

  7. 034 Maven中的dependencyManagement和dependencies区别

    这个标签使用过,但是具体的描述还是没有说明过.在这里,专门查了一下,写了这篇文章. 1.定义 在Maven中dependencyManagement的作用其实相当于一个对所依赖jar包进行版本管理的管 ...

  8. day 47 htm-part2

    列表 无序列表====所谓无序就是显示出来的效果没有编号排序 <ul type='disc'> <li>第一项</li> <li>第二项</li& ...

  9. VC9、VC11、VC14、VC15库 32位 64位 免费下载

    VC9.VC11.VC14.VC15库 32位 64位 免费下载 更新版本的PHP是用VC11,VC14或VC15(分别为Visual Studio 2012,2015或2017编译器)构建的,并且包 ...

  10. stm32中断优先级管理与外部中断编程

    stm32中断优先级管理与外部中断编程 中断优先级管理 外部中断编程 官方示例程序 exti.h #ifndef __EXTI_H #define __EXIT_H #include "sy ...