关于 Bash 脚本中 Shebang 的趣事

关于,bash,脚本,shebang,趣事 · 浏览次数 : 254

小编点评

**Shebang 行的作用** Shebang 行是用于指定脚本的解释器路径的符号,它出现在脚本的第一行,以 #! 开头。 **Shebang 行的格式** Shebang 行的格式如下: ```bash # interpreter_path ``` 其中: * **interpreter_path** 是一个指向解释器的绝对路径或一个指向解释器的相对路径。 **Shebang 行的作用** Shebang 行告诉操作系统执行脚本时,该脚本的解释器路径。当脚本以 #! 开头时,操作系统会寻找该脚本文件的第一个行,以寻找解释器路径。如果脚本文件包含解释器路径,操作系统会使用该路径来执行脚本。 **示例** 假设我们有一个名为 `test.sh` 的脚本,其解释器路径为 `/usr/bin/bash`,那么它的 shebang 行将如下格式: ```bash #!/usr/bin/bash ``` **执行脚本的几种方式** * **使用绝对路径** ```bash ./test.sh ``` * **使用相对路径** ```bash ../test.sh ``` * **使用 `sh` 命令** ```bash sh test.sh ``` * **使用 `bash` 命令** ```bash bash test.sh ``` **注意** * 如果脚本没有定义 shebang 行,系统会使用默认的解释器。 * Shebang 行只能指定一个解释器路径。 * 绝对路径必须以 `/` 或 `./` 开头。

正文

哈喽大家好,我是咸鱼

不知道小伙伴们在写 Bash 脚本或者说看别人的 Bash 脚本的时候有没有注意过脚本的第一行

#!/bin/bash

Bash 脚本的第一行往往以 #! 开头,这一行称作 shebang 行

在 类 UNIX 系统中,shebang 行用来指定脚本的解释器路径,通常出现在第一行,格式如下

#! interpreter_path

shebang 行中开头 #! 字符的作用是告诉操作系统这不是一个普通二进制文件,而是需要通过解释器运行的东西

而这个解释器则通过 #! 字符后面来指定。例如 /bin/bash 表示使用 bash 解释器来执行该脚本文件

下面则是一些 Bash 脚本的 shebang 行,指定了不同的解释器

#! /usr/bin/perl
#! /usr/bin/awk
#! /usr/bin/python

那么这时候小伙伴们可能就会有疑问:我忘了加 shebang 行,脚本为什么还能执行?

如果一个脚本没有添加 shebang 行来指定解释器路径,则默认情况下系统会使用默认的 shell 来执行脚本,系统默认的 shell 可以通过下面的命令来查看

# 一般情况下默认的 shell 为bash
echo $SHELL

现在我们知道了 shebang 行的作用,那么我们现在来编写一个脚本并修改 shebang 行试试

test.sh 内容如下:

#!/bin/bash
echo Hello

先给 test.sh 脚本添加一下执行权限

chmod +x test.sh

接下来我们用几种方式来执行这个脚本

可以看到脚本都成功执行了

下面我们来改一下 shebang 行,将其改成其他命令

#!/usr/bin/ls -l
echo Hello

然后我们分别用几种方式来执行这个脚本

上面脚本执行的结果是不是看的一脸懵逼,说实话我一开始看到的时候也是很懵

我们先来看下这四种脚本执行方式的区别

  • bash tesh.sh

这种方式执行脚本的原理是将 test.sh 作为参数传给 bash 解释器(命令)来执行,而不是 test,sh 自己来执行

这种方式执行脚本不需要给脚本文件添加执行权限、不需要写 shebang 行指定解释器路径,因为脚本是作为参数被传给 bash 来执行

  • sh test.sh

这种执行脚本的方式跟上面的方式原理一样,都是将脚本作为参数传进去,只不过是这个方式用的是 sh 解释器(命令),而不是 bash

  • /root/test.sh

这种是通过绝对路径去执行脚本,通过绝对路径来执行脚本就需要脚本拥有执行权限

当使用绝对路径来执行脚本时,操作系统需要知道该脚本文件所使用的解释器类型,这就需要依靠脚本文件中的 shebang 行

实际上你用绝对路径执行脚本的时候,如果里面定义了 shebang 行(例如 #! /bin/bash

那么实际上跟下面的命令是一样的

/bin/bash /root/test.sh

在执行脚本的时候,操作系统会读取脚本的 shebang 行

如果你的 shebang 行是其他 Linux 命令而不是解释器,那么就会导致操作系统将你的 shebang 行当作命令,而你的脚本则是命令的参数

就好比上面的例子,我将 shebang 行改成了 #! /usr/bin/ls -l ,当我执行脚本的时候其实就是下面这样的

/usr/bin/ls -l /root/test.sh

这样会导致脚本无法执行

  • ./test.sh

这种是通过相对路径去执行脚本,跟上面用绝对路径执行脚本方式是一样的,只不过区别是一个是相对路径一个是绝对路径

总结:

  • shebang 行通常出现在 UNIX 系统的脚本当中,用来指定脚本的解释器路径,出现在第一行,以 #! 开头
  • 如果脚本里面没有定义 shebang 行,系统会去找默认的解释器,默认解释器用 echo $SHELL 查看
  • 用 bash 或者 sh 命令执行脚本的时候,其实是把脚本作为参数传给 bash 或 sh 命令了,这时候脚本可以不添加执行权限、可以不需要 shebang 行
  • 如果用绝对路径或者相对路径的方式来执行脚本,需要脚本拥有执行权限,如果 shebang 行定义的不是解释器而是其他命令,就会导致脚本无法执行

附上参考链接:Shebang Shenanigans :: Linus Karlsson

与关于 Bash 脚本中 Shebang 的趣事相似的内容:

关于 Bash 脚本中 Shebang 的趣事

哈喽大家好,我是咸鱼 不知道小伙伴们在写 Bash 脚本或者说看别人的 Bash 脚本的时候有没有注意过脚本的第一行 #!/bin/bash Bash 脚本的第一行往往以 #! 开头,这一行称作 shebang 行 在 类 UNIX 系统中,shebang 行用来指定脚本的解释器路径,通常出现在第一

Linux Bash Shell 中变量的 5 个易错点

Linux 中的 Bash 脚本支持对变量的操作,下面咸鱼将介绍 Linux Bash Shell 中关于变量的 5 个易错点 因为编程习惯,这类现象往往发生在大多数使用过其他流行编程语言的程序员身上 变量赋值 对于许多编程语言(例如 Python),变量赋值的时候在等号两边添加空格是一个好的习惯

bash shell 无法使用 perl 正则

哈喽大家好,我是咸鱼。今天跟大家分享一个关于正则表达式的案例,希望能够对你有所帮助 案例现象 前几天有一个小伙伴在群里求助,说他这个 shell 脚本有问题,让大家帮忙看看 可以看到,这个脚本首先将目标文本文件的名字当作该脚本的第一个参数($1)传递进去,然后查看这个文本文件的内容(cat $1),

【转帖】nginx变量使用方法详解-2

https://www.diewufeiyang.com/post/576.html 关于 Nginx 变量的另一个常见误区是认为变量容器的生命期,是与 location 配置块绑定的。其实不然。我们来看一个涉及“内部跳转”的例子: Bash server { listen 8080; locati

Linux:进程模型和进程管理

在Linux系统中,执行一个程序或命令就可以触发一个进程,系统会给予这个进程一个ID,称为PID,同时根据触发这个进程的用户与相关属性关系,基于这个PID一组有效的权限设置。举个常见的例子,我们要操作系统的时候通常是利用ssh连接程序或直接在主机上登录,然后获取shell。默认的shell是bash,对应的路径为/bin/bash,那么同时间的每个人登录都是执行/bin/bash,不过每个人获取的

关于面向对象的方法并行执行的问题

LabVIEW的从同一个类实例化的多个对象如何执行各自的方法呢? 这几天跟同事讨论到LabVIEW的面向对象编程中,如果我设计的一个类有一个方法比较耗时,那么当我实例化多个对象时,那么这个耗时的方法是怎么执行的呢?是各自并行执行还是,必须等某一个对象的方法调用完,接下来调用第二个对象的该方法呢? 接

关于ComfyUI的一些Tips

关于ComfyUI的一些Tips 前言: 最近发的ComfyUI相关文章节奏不知道会不会很快,在创作的时候没有考虑很多,想着把自己的知识分享出去。后台也看到很多私信,有各种各样的问题,这是我欠缺考虑了,今天这篇文章呢,根据私信的问题我大致整理了一下,给大家一些小tips。 目录 一、将 ComfyU

关于领域驱动设计,大家都理解错了

翻遍整个互联网,我发现,关于领域驱动设计,大家都**理解错了**。 今天,我们尝试通过一篇文章的篇幅,给大家展示一个完全不同的视角,把“领域驱动设计”这六个字解释清楚。 ## 领域驱动设计学习资料现状 领域驱动设计的概念提出已经有20年的时间了,整个互联网充斥着大量书籍、文章和视频教程,这里我列举几

关于docker-compose up -d 出现超时情况处理

由于要搭建一个ctf平台,用docker一键搭建是出现超时情况 用了很多办法,换源,等之类的一样没办法,似乎它就是只能用官方那个一样很怪。 只能用一种笨办法来处理了,一个个pull。 打个比如: 打开相对应docker-compose.yml文件 可以看到image就是需要去下载的。那么此时你就可以

关于 KL 散度和变分推断的 ELBO

ELBO 用于最小化 q(z|s) 和 p(z|s) 的 KL 散度,变成最大化 p(x|z) 的 log likelihood + 最小化 q(z|s) 和先验 p(z) 的 KL 散度。