关于#!/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. java.net.UnknownHostException: master

    1:如果你报这个错误,第一反应应该是本地的host文件没有配置服务器名称和对应的ip地址,这个反应就对了.贴一下错误和解决方法: java.net.UnknownHostException: mast ...

  2. 一脸懵逼学习Struts数据校验以及数据回显,模型驱动,防止表单重复提交的应用。

    1:Struts2表单数据校验: (1)前台校验,也称之为客户端校验,主要是通过Javascript编程的方式进行数据的验证. (2)后台校验,也称之为服务器校验,这里指的是使用Struts2通过xm ...

  3. Android Studio运行项目报错:Error:null value in entry: annotationProcessorOutputFolder=null的解决方案

    一般是在Android studio异常退出(比如强制关机)后,重新打开后运行项目出现该问题. 解决方案 删除项目根目录的.gradle文件夹,然后Clean  Project —— Rebulid ...

  4. Java基础知识➣序列化与反序列化(四)

    概述 Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据.有关对象的类型的信息和存储在对象中数据的类型. 将序列化对象写入文件之后,可以从文件 ...

  5. 【译】学习JavaScript中提升、作用域、闭包的终极指南

    这似乎令人惊讶,但在我看来,理解JavaScript语言最重要和最基本的概念是理解执行上下文.通过正确学习它,你将很好地学习更多高级主题,如提升,作用域链和闭包.考虑到这一点,究竟什么是"执 ...

  6. 一起学Hive——详解四种导入数据的方式

    在使用Hive的过程中,导入数据是必不可少的步骤,不同的数据导入方式效率也不一样,本文总结Hive四种不同的数据导入方式: 从本地文件系统导入数据 从HDFS中导入数据 从其他的Hive表中导入数据 ...

  7. gcc make 与cmake

    1. gcc (1)是什么? 它是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器.它可以编译很多种编程语言(括C.C++.Objective-C.For ...

  8. Python学习(三十一)—— Django之路由系统

    转载自:http://www.cnblogs.com/liwenzhou/p/8271147.html Django的路由系统 Django 1.11版本 URLConf官方文档 URL配置(URLc ...

  9. Codeforces 911F Tree Destruction

    Tree Destruction 先把直径扣出来, 然后每个点都和直径的其中一端组合, 这样可以保证是最优的. #include<bits/stdc++.h> #define LL lon ...

  10. ELK使用1-Elasticsearch使用

    一.es 1.通过curl命令获取es进群信息 a.curl -i(设置协议的头信息) -XGET 'http:192.168.30.41:9200/_count' b.查看集群状态 curl -XG ...