linux脚本中 #!/bin/sh、#!/bin/bash

我们通常看到的脚本文件总是有以下这样的开头:

#!/bin/bash

本文解释一下这是什么,以及为什么要写它。

首先解释一下 #! ,因为 #!有个专有的名词,叫 shebang

发音类似中文的 "蛇棒" 。为什么叫 shebang 呢? 首先 # 的英文是 sharp, 而 感叹号 ! 经常被引用为炸弹,炸弹爆炸就是 bang , 所以 sharp+bang,简读为 shebang

后面的 /bin/bash 就比较熟悉了,它是 Bash Shell 的二进制执行文件路径。是 Unix 类操作系统中最常用的 Shell 程序之一。

所以 #!/bin/bash 的作用是:用于指定默认情况下运行指定脚本的解释器

当脚本以 #!/bin/bash 开头时,内核就知道用 /bin/bash 这个可执行文件来解释并运行这个脚本。

下面举个例子来说明下:

一、当脚本中指定脚本解释器为#!/bin/bash、#!/bin/sh时,shell脚本test.sh的执行情况

#!/bin/sh

echo "Hello, world!"

# 使用 Bash 特有的语法
if [[ 1 -eq 1 ]]; then
  echo "1 equals 1"
fi

这个脚本使用了bash特有的语法[[ ... ]],如果使用 #!/bin/sh 来指定解释器,则会报错:

test.sh: 6: test.sh: [[: not found

分以下三种情况执行此test.sh脚本:

1、脚本中指定了#!/bin/sh,且脚本执行时使用sh,则执行时会报错

#sh test.sh
Hello, world!
test.sh: 6: test.sh: [[: not found

2、脚本中指定了#!/bin/sh,且脚本执行时使用bash,则执行正常

#bash test.sh
Hello, world!
1 equals 1

3、给test.sh添加执行权限后再执行,也报错

#chmod +x test.sh
#./test.sh
Hello, world!
./test.sh: 6: ./test.sh: [[: not found

由上可知,当执行脚本时,如果命令中指定了解释器bash、sh,如:bash test.sh,则执行时会忽略脚本中第一行指定的解释器,即#!/bin/sh#!/bin/bash会被忽略,而以bash进行解释脚本。

二、当脚本中未指定解释器时,shell脚本test1.sh的执行情况

echo "Hello, world!"

# 使用 Bash 特有的语法
if [[ 1 -eq 1 ]]; then
  echo "1 equals 1"
fi

此脚本第一行未指定任何解释器。

分以下三种情况执行此test1.sh脚本:

1、脚本中未指定解释器,且脚本执行时使用sh,则执行时会报错

#sh test1.sh
Hello, world!
test.sh: 6: test.sh: [[: not found

2、脚本中未指定解释器,且脚本执行时使用bash,则执行正常

#bash test1.sh
Hello, world!
1 equals 1

3、给test1.sh添加执行权限后再执行,执行正常

#chmod +x test1.sh
#./test1.sh
Hello, world!
1 equals 1

由上可知,当执行脚本时,如果命令中指定了解释器bash、sh,如:bash test.sh,则执行时以bash进行解释脚本;如果命令中未指定解释器bash、sh,如:./test.sh,则执行时会以系统默认的解释器进行解释,而bash是 Unix 类操作系统中最常用的 Shell 程序之一。

通过 echo $0 可查看系统默认的脚本解释器,如以下是我的ubuntu系统默认的解释器:

#echo $0
bash

三、当脚本中指定解释器为:#!/bin/cat,即将cat 命令将成为 shell 的解释器,则shell脚本test2.sh的执行情况

#!/bin/cat
echo "Hello, world!"

# 使用 Bash 特有的语法
if [[ 1 -eq 1 ]]; then
  echo "1 equals 1"
fi

分以下三种情况执行此test2.sh脚本:

1、脚本中未指定解释器,且脚本执行时使用sh,则执行时会报错

#sh test2.sh
Hello, world!
test.sh: 6: test.sh: [[: not found

2、脚本中未指定解释器,且脚本执行时使用bash,则执行正常

#bash test2.sh
Hello, world!
1 equals 1

3、给test2.sh添加执行权限后再执行,执行正常

#chmod +x test2.sh
#./test2.sh
#!/bin/cat

echo "Hello, world!"

# 使用 Bash 特有的语法
if [[ 1 -eq 1 ]]; then
  echo "1 equals 1"
fi

这意味着现在这个脚本将使用 cat 命令运行并显示脚本的内容。它将输出脚本所有内容。

由上面的三种情况可知:

1、当执行脚本的方式为:./test.sh时,如果脚本中未指定shebang解释器,则以系统默认的解释器进行解释执行;如果脚本中指定了shebang解释器,则以指定的解释器进行解释执行。

2、当执行脚本的方式为:bash test.sh时,不管脚本是否指定了shebang解释器,都会被忽略,而以bash作为解释器进行解释执行``。

参考:

为什么 shell 脚本的开头要写 #!/bin/bash - 知乎

【Linux】#!/bin/sh与#!/bin/bash,区别是什么,结合代码举例说明以及常见的异常情况处理-CSDN博客

相关推荐
_.Switch4 分钟前
Python 自动化运维持续优化与性能调优
运维·开发语言·python·缓存·自动化·运维开发
南猿北者9 分钟前
Docker Volume
运维·docker·容器
矛取矛求3 小时前
Linux如何更优质调节系统性能
linux
内核程序员kevin4 小时前
在Linux环境下使用Docker打包和发布.NET程序并配合MySQL部署
linux·mysql·docker·.net
kayotin4 小时前
Wordpress博客配置2024
linux·mysql·docker
Ztiddler5 小时前
【Linux Shell命令-不定期更新】
linux·运维·服务器·ssh
小小不董5 小时前
Oracle OCP认证考试考点详解082系列16
linux·运维·服务器·数据库·oracle·dba
IPdodo全球网络5 小时前
如何利用静态住宅IP优化Facebook商城的网络稳定性与运营效率
运维·服务器
a1denzzz5 小时前
Linux系统的网络设置
linux·服务器·网络
运维&陈同学6 小时前
【模块一】kubernetes容器编排进阶实战之k8s基础概念
运维·docker·云原生·容器·kubernetes·云计算