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

一、含义

#!/bin/sh是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面根的是此解释此脚本的shell的路径。

其实第一句的#!是对脚本的解释器程序路径,脚本的内容是由解释器解释的,我们可以用各种各样的解释器来写对应的脚本。

比如说/bin/csh脚本,/bin/perl脚本,/bin/awk脚本,/bin/sed脚本,甚至/bin/echo等等。

#!/bin/bash同理。

二、区别

GNU/Linux操作系统中的/bin/sh本是bash (Bourne-Again Shell) 的符号链接,但鉴于bash过于复杂,有人把bash从NetBSD移植到Linux并更名为dash (Debian Almquist Shell),并建议将/bin/sh指向它,以获得更快的脚本执行速度。Dash Shell 比Bash Shell小的多,符合POSIX标准。

Ubuntu继承了Debian,所以从Ubuntu 6.10开始默认是Dash Shell。

应该说,/bin/sh与/bin/bash虽然大体上没什么区别,但仍存在不同的标准。标记为#!/bin/sh的脚本不应使用任何POSIX没有规定的特性 (如let等命令, 但#!/bin/bash可以)。Debian曾经采用/bin/bash更改/bin/dash,目的使用更少的磁盘空间、提供较少的功能、获取更快的速度。但是后来经过shell脚本测试存在运行问题。因为原先在bash shell下可以运行的shell script (shell 脚本),在/bin/sh下还是会出现一些意想不到的问题,不是100%的兼用。

上面可以这样理解,使用man sh命令和man bash命令去观察,可以发现sh本身就是dash,也就更好的说明集成Debian系统之后的更改。

补充
脚本test.sh内容:
#!/bin/sh
source pcy.sh #pcy.sh并不存在
echo hello
执行./test.sh,屏幕输出为:
./test.sh: line 2: pcy.sh: No such file or directory
由此可见,在#!/bin/sh的情况下,source不成功,不会运行source后面的代码。
修改test.sh脚本的第一行,变为#!/bin/bash,再次执行./test.sh,屏幕输出为:
./test.sh: line 2: pcy.sh: No such file or directory
hello
由此可见,在#!/bin/bash的情况下,虽然source不成功,但是还是运行了source后面的echo语句。
但是紧接着我又试着运行了一下sh ./test.sh,这次屏幕输出为:
./test.sh: line 2: pcy.sh: No such file or directory
表示虽然脚本中指定了#!/bin/bash,但是如果使用sh 方式运行,如果source不成功,也不会运行source后面的代码。

Linux source命令:

通常用法:source filepath 或 . filepath

功能:使当前shell读入路径为filepath的shell文件并依次执行文件中的所有语句,通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。例如,当我们修改了/etc/profile文件,并想让它立刻生效,而不用重新登录,就可以使用source命令,如source /etc/profile。

source命令(从 C Shell 而来)是bash shell的内置命令;点命令(.),就是个点符号(从Bourne Shell而来)是source的另一名称。这从用法中也能看出来。

source filepath 与 sh filepath 、./filepath的区别:

当shell脚本具有可执行权限时,用sh filepath与./filepath是没有区别的。./filepath是因为当前目录没有在PATH中,所有"."是用来表示当前目录的。

sh filepath 会重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell是新建的,其改变的变量不会被带回父shell,除非使用export。

source filename其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。

举例说明:

新建一个test.sh脚本,内容为:A=1;

修改其可执行权限:chmod +x test.sh;

运行sh test.sh后,echo $A,显示为空,因为A=1并未传回给当前shell;

运行./test.sh后,也是一样的效果;

运行source test.sh 或者 . test.sh,然后echo $A,则会显示1,说明A=1的变量在当前shell中;

Linux中exec命令相关:

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息。
  bash shell的命令分为两类:外部命令和内部命令。外部命令是通过系统调用或独立的程序实现的,如sed、awk等等。内部

命令是由特殊的文件格式(.def)所实现,如cd、history、exec等等。

  在说明exe和source的区别之前,先说明一下fork的概念。

  fork是linux的系统调用,用来创建子进程(child process)。子进程是父进程(parent process)的一个副本,从父进程那里

获得一定的资源分配以及继承父进程的环境。子进程与父进程唯一不同的地方在于pid(process id)。

  环境变量(传给子进程的变量,遗传性是本地变量和环境变量的根本区别)只能单向从父进程传给子进程。不管子进程的环境

变量如何变化,都不会影响父进程的环境变量。

  shell script:

  有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不

再启用其他shell。

  新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句

  #!/bin/sh

  一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

  另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。

  source:

  source命令即点(.)命令。

  在bash下输入man source,找到source命令解释处,可以看到解释”Read and execute commands from filename in the

current shell environment and …”。从中可以知道,source命令是在当前进程中执行参数文件中的各个命令,而不是另起子

进程(或sub-shell)。

  exec:

  在bash下输入man exec,找到exec命令解释处,可以看到有”No new process is created.”这样的解释,这就是说exec命

令不产生新的子进程。那么exec与source的区别是什么呢?

  exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。

系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的

进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。

  一个进程主要包括以下几个方面的内容:

  (1)一个可以执行的程序

  (2) 与进程相关联的全部数据(包括变量,内存,缓冲区)

  (3)程序上下文(程序计数器PC,保存程序执行的位置)

#!/bin/bash和#!/bin/sh的区别,source命令和exec命令相关推荐

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

    Linux脚本开头#!/bin/bash和#!/bin/sh是什么意思以及区别 一.意思 #!/bin/sh是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面根的是此解释此脚本的she ...

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

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

  3. #!/bin/bash和#!/bin/sh是什么意思以及区别

    尊重原著,著明:本帖为优秀的帖子整合 一.意思 #!/bin/sh是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面根的是此解释此脚本的shell的路径. 其实第一句的#!是对脚本的解 ...

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

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

  5. Shell脚本中:#!/bin/bash和#!/bin/sh

    转自:https://www.cnblogs.com/jonnyan/p/8798364.html 本文参考:https://www.cnblogs.com/aaronLinux/p/6885288. ...

  6. Linux 脚本文件中开头的#!/bin/bash和#!/bin/sh是什么意思

    解释 #!/bin/sh:表示此脚本使用 /bin/sh 来解释执行,#! 是特殊的表示符,其后面跟的是解释此脚本的 shell 的路径. 我们知道 shell 有很多种,例如,bash.csh.sh ...

  7. Shell脚本中:#!/bin/bash和#!/bin/sh是什么意思以及区别?

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

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

    #!/bin/bash 是指此脚本使用/bin/bash来解释执行. 其中,#!是一个特殊的表示符,其后,跟着解释此脚本的shell路径. bash只是shell的一种,还有很多其它shell,如:s ...

  9. bash、dash(/bin/bash和/bin/sh)

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

最新文章

  1. ectouch java_ectouch第七讲 之ECshop模板机制整理
  2. 后盾网lavarel视频项目---3、lavarel中子控制器继承父控制器以判断是否登录
  3. IO对象不可以复制或者赋值
  4. MySQL的JOIN原理
  5. Robotium_断言方法assert、is、search
  6. 新款苹果电脑_苹果真牛!iPhone的软件,苹果电脑上也照样可用了
  7. QueryPath, php上的jQuery
  8. python提取tuple列表中的特定位置的值
  9. JSP程序开发学习笔记2
  10. Mellanox能给英伟达带来什么?
  11. String类型转换成json对象
  12. curl安装失败/区块链配置
  13. 前端新手小白必看--最全静态网页模板网站
  14. postman插件4.1.3的安装(亲测,可以用)
  15. 怎么设置计算机语言中文,Windows10 IE11浏览器怎么把默认语言设置为中文
  16. EXCEL与数据分析
  17. 实用性室内地图导航软件
  18. 周杰伦专辑《最伟大的作品》在哪看?当贝盒子畅享周董最新MV
  19. Android 创建快捷方式图标
  20. Swift-字符串和字符

热门文章

  1. 云虚拟主机连接mysql_云虚拟主机数据库使用
  2. 股票交易日(动态规划)----美团2016研发工程师编程题(二)
  3. 地下交通站之贾贵经典语录
  4. NB-IoT和LTE远程通讯方案选择
  5. 《微积分基础》学习(一)
  6. 小程序开发框架mpvue开发文档
  7. iframe 嵌入页面后无法显示的问题
  8. mmse评估量表_简易精神状态评价量表(MMSE)
  9. 四川成都攻防大赛技术细节
  10. webpack中处理css文件