关于 Bash 脚本中 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

接下来我们用几种方式来执行这个脚本
关于 Bash 脚本中 Shebang 的趣事
可以看到脚本都成功执行了

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

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

然后我们分别用几种方式来执行这个脚本
关于 Bash 脚本中 Shebang 的趣事
上面脚本执行的结果是不是看的一脸懵逼,说实话我一开始看到的时候也是很懵

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

  • 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

原文链接:https://www.cnblogs.com/edisonfish/p/17379964.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于 Bash 脚本中 Shebang 的趣事 - Python技术站

(0)
上一篇 2023年5月7日
下一篇 2023年5月8日

相关文章

  • Linux用户管理

    1、基本介绍   用户管理图解           说明:     1)、Linux系统是一个多用户多任务的操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。     2).、Linux的用户至少要属于一个组。 2、添加用户   基本语法     useradd  [选项]  用户名        细节…

    Linux 2023年4月12日
    00
  • 详解CentOS8更换yum源后出现同步仓库缓存失败的问题

    针对“详解CentOS8更换yum源后出现同步仓库缓存失败的问题”的解决方案,以下是完整攻略: 问题背景 当我们在CentOS 8系统上更换yum源时,可能会出现同步yum缓存失败的情况。这种情况一般是由于新的yum源中的某些包缺失或者有误导致的。为了解决这个问题,我们可以将yum源回退到缺少包的版本或者修复缺少包的问题。 解决方案 针对上述问题,我们可以尝…

    Linux 2023年5月14日
    00
  • CentOS下Cobbler的安装和配置教程

    CentOS下Cobbler的安装和配置教程 什么是Cobbler Cobbler是一个Linux系统安装服务器,可以自动化安装和配置新的操作系统实例。它可以自动配置kickstart安装环境、DHCP、DNS和TFTP服务,并支持许多Linux发行版,如CentOS、Debian、Fedora等。 安装Cobbler 下载并安装EPEL软件源 $ yum …

    Linux 2023年5月14日
    00
  • Linux内核符号表【转】

    我们知道insmod使用公共内核符号表来解析模块中未定义的符号。公共内核符号表中包含了所有 的全局内核项(即函数和变量)的地址,这是实现模块化驱动程序所必需的。当模块被装入内核 后,它所导出的任何内核符号都会变成内核符号表的一部分。在通常情况下,模块只需实现自己 的功能,而无需导出任何符号。但是,如果其他模块需要从某个模块中获得好处时,我们也可以 导出符号。…

    Linux 2023年4月11日
    00
  • CentOS7系统下用YUM安装Nginx详解

    下面是在CentOS7系统下使用YUM安装Nginx的详细攻略: 安装Nginx 步骤如下: 打开终端,使用root用户登录系统; 更新YUM: yum update 安装Nginx: yum install nginx 启动Nginx: systemctl start nginx 检查Nginx是否已经启动成功: systemctl status ngin…

    Linux 2023年5月14日
    00
  • linux下can调试工具canutils安装与使用

    0、  编译环境所需要的工具 libsocketcan-0.0.11.tar.bz2 canutils-4.0.6.tar.bz2 下载路径 https://public.pengutronix.de/software/libsocketcan/libsocketcan-0.0.11.tar.bz2 #0.0.11版本 https://public.peng…

    Linux 2023年4月11日
    00
  • Linux下安装DedeCMS及安全设置教程

    Linux下安装DedeCMS及安全设置教程 介绍 DedeCMS是一款功能强大的内容管理系统,是国内开发的一款CMS系统。本文将详细介绍在Linux系统下如何安装DedeCMS,并对其进行安全设置。 步骤 1. 安装LAMP环境 在安装DedeCMS之前,需要先搭建好LAMP环境。LAMP指的是Linux + Apache + MySQL + PHP的组合…

    Linux 2023年5月24日
    00
  • Linux优化之IO子系统监控与调优

    Linux优化之IO子系统 作为服务器主机来讲,最大的两个IO类型 : 1.磁盘IO  2.网络IO 这是我们调整最多的两个部分所在   磁盘IO是如何实现的 在内存调优中,一直在讲到为了加速性能,linux内核一般情况下都会尝试将磁盘上的慢速设备上的文件缓存至内存中,从而达到加速效果; 虚拟内存的概念: 读写都在内存中完成,当某一进程在cpu运行的时候,进…

    Linux 2023年4月12日
    00
合作推广
合作推广
分享本页
返回顶部