释伴:Linux 上的 Shebang 符号(#!)

2023-10-27

  使用类Unix系统的同学可能都对“#!”这个符号并不陌生,但是你真的了解它吗?


这里写图片描述

这个符号的名称,叫做”Shebang”或者”Sha-bang”。长期以来,Shebang都没有正式的中文名称。Linux中国翻译组的GOLinux将其翻译为“释伴”,即“解释伴随行”的简称,同时又是Shebang的音译。本文将简单介绍一下Shebang这个符号。


1.词源与历史

  Shebang 的名字来自于 SHArp 和 bang,或 haSH bang 的缩写,指代 Shebang 中 #! 两个符号的典型 Unix 名称。 Unix 术语中,井号通常称为 sharp,hash 或 mesh;而叹号则常常称为 bang。也有看法认为,shebang 名字中的 sh 来自于默认shell Bourne shell 的名称,sh,因为常常使用 shebang 调用之。
  在2010年版的 Advanced bash scripting guide(revision 6.2)中,Shebang 被称为 “sha-bang”,同时提到”也写作 she-bang 或 sh-bang”,但该文件中没有提到 “shebang” 这一形式。

2.用法

  Shebang通常出现在类Unix系统的脚本中第一行,作为前两个字符。在Shebang之后,可以有一个或数个空白字符,后接解释器的绝对路径,用于指明执行这个脚本文件的解释器。在直接调用脚本时,系统的程序载入器会分析 Shebang 后的内容,将这些内容作为解释器指令,并调用该指令,将载有 Shebang 的文件路径作为该解释器的参数,执行脚本,从而使得脚本文件的调用方式与普通的可执行文件类似。例如,以指令#!/bin/sh开头的文件,在执行时会实际调用 /bin/sh 程序(通常是 Bourne shell 或兼容的 shell,例如 bash、dash 等)来执行。
  由于 # 符号在许多脚本语言中都是注释标识符,Shebang 的内容会被这些脚本解释器自动忽略。 在 # 字符不是注释标识符的语言中,例如 Scheme,解释器也可能忽略以 #! 开头的首行内容,以提供与 Shebang 的兼容性。

  Shebang的一些具体用法罗列如下:

1、如果脚本文件中没有#!这一行,那么执行时会默认采用当前Shell去解释这个脚本(即:$SHELL环境变量)。
2、如果#!之后的解释程序是一个可执行文件,那么执行这个脚本时,它就会把文件名及其参数一起作为参数传给那个解释程序去执行。
3、如果#!指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission
denied”。如果#!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。
4、如果#!指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。注意:#!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。
5、当然,如果你使用类似于”bash test.sh”这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是用命令行中显式指定的bash。
6、脚本文件必须拥有可执行权限。


  Shebang的好处在于,允许脚本和数据文件充当系统命令,无需在调用时由用户指定解释器,从而对用户和其它程序隐藏其实现细节。下面我们一起来看几个典型的例子:

#!/bin/sh:使用 sh,即 Bourne shell 或其它兼容 shell 执行脚本
#!/bin/csh:使用 csh,即 C shell 执行
#!/usr/bin/perl -w:使用带警告的 Perl 执行
#!/usr/bin/python -O:使用具有代码优化的 Python 执行
#!/usr/bin/php:使用 PHP 的命令行解释器执行

Shebang 行也可以包含需要传递到解释器的特定选项(如上述的 Perl 和 Python 例子)。

这里有两点需要注意的地方:

(1).之前我们提到过,解释器指令本身会被解释器认为是单纯的注释而跳过。 然而,并不是每一种解释器都会自动忽略Shebang行,例如对于下面的脚本,

#!/bin/cat
Hello world!

cat 会把文件中的两行都输出到标准输出中。

(2).使用 #!/usr/bin/env 脚本解释器名称 是一种常见的在不同平台上都能正确找到解释器的办法。因为env一般固定在/usr/bin目录下,而其余解释器的安装位置就相对不那么固定。但是,用env时你应该注意这么一个事实:传递给解释器的argv和你想象得并不一样。下面这个就是不对的:

#!/usr/bin/env perl -w

shell会提示:/usr/bin/env: perl -w: No such file or directory。错误的根源就在于 perl -w 被当成了整体传递给env。

  最后,我们来总结一下Shebang的几点要求:

#! 必须连接在一起
#! 一句必须在文件的最开始,第一行
# 开头的语句一般情况下会被当成注释而忽略,所以Shebang 对文件的内容是没有影响的
#! 开头的一行会设置解释器运行环境

参考文献

[1] https://zh.wikipedia.org/wiki/Shebang
[2] http://blog.csdn.net/fivedoumi/article/details/51030296
[3] http://www.cnblogs.com/lwm-1988/archive/2011/08/30/2159446.html
[4] http://lukeat.me/2017/03/28/%E5%85%B3%E4%BA%8E%E8%84%9A%E6%9C%AC%E6%96%87%E4%BB%B6%E7%9A%84%E7%AC%AC%E4%B8%80%E8%A1%8C-Shebang/
[5] http://blog.sciencenet.cn/blog-204973-1027540.html
以上为本文的全部参考文献,对原作者表示感谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

释伴:Linux 上的 Shebang 符号(#!) 的相关文章

  • numpy 未定义符号:PyFPE_jbuf

    我正在尝试使用一百万首歌曲数据集 为此我必须安装 python 表 numpy cython hdf5 numexpr 等 昨天我设法安装了我需要的所有内容 在使用 hdf5 遇到一些麻烦之后 我下载了预编译的二进制包并将它们保存在我的 b
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • 构建 makefile 依赖/继承树

    如果我解释得不好或者问了一些明显的问题 我很抱歉 但我是 Linux 内核的新手 而且有点深入 我们有一个嵌入式 Linux 系统 它附带一个 文档非常糟糕的 SDK 其中包含数百个文件夹stuff 大多数文件夹包含rules make m
  • 无法安装 WWW::Curl::Easy: SZBALINT/WWW-Curl-4.17.tar.gz : make NO

    我正在尝试在我的 Fedora 26 机器上安装 WWW Curl Easy gcc c I usr include D REENTRANT D GNU SOURCE O2 g pipe Wall Werror format securit
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void
  • 如何不断刷新屏幕并实时更新[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在linux上写一个C程序 不断刷新屏幕并实时更新 例如类似于top终端中的命令 谁能指出我正确的方向 为了保持它跨终端类型的可移
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • 从 TypeScript 运行任何 Linux 终端命令?

    有没有办法直接从 TypeScript 类中执行 Linux 终端命令 这个想法是做类似的事情 let myTerminal new LinuxTerminal let terminalResult myTerminal run sudo
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • 没有可用的符号表信息

    我正在测试第三方的库 它崩溃了 当我想查看崩溃的原因时 我的 gdb 告诉我没有可用的调试符号 Program received signal SIGSEGV Segmentation fault Switching to Thread 0
  • 如何使用 sed 仅删除双空行?

    我找到了这个问题和答案 https stackoverflow com questions 4651591 howto use sed to remove only triple empty lines关于如何删除三重空行 但是 我只需要对
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • Godaddy 托管上的 CakePHP 控制台

    我一直在努力让我的 CakePHP 网站在 Godaddy 网格托管 帐户上运行 我的蛋糕应用程序设置是从帐户的子目录托管的 并且可以通过子域访问 我必须调整我的 htaccess 文件才能使其正常工作 现在我需要让 CakePHP 控制台
  • 在Linux上编译C# + WPF以便在Windows上运行

    我有一个 C 应用程序 其中某些部分是使用 WPF 编写的 Mono 不支持 可以在 Linux 上编译这个应用程序吗 最终 该应用程序将在 Windows 上运行 但它是更大框架的一部分 并且我们的整个构建过程在 Linux 上运行 因此
  • ansible 重新启动 2.1.1.0 失败

    我一直在尝试创建一个非常简单的 Ansible 剧本 它将重新启动服务器并等待它回来 我过去在 Ansible 1 9 上有一个可以运行的 但我最近升级到 2 1 1 0 并且失败了 我正在重新启动的主机名为 idm IP 为 192 16
  • Locale.getDefault() 始终返回 en

    unix 机器上的服务器始终使用 en 作为默认区域设置 以下是区域设置输出 LANG en US LC CTYPE C LC NUMERIC C LC TIME C LC COLLATE C LC MONETARY C LC MESSAG
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案

随机推荐

  • 自定义view之水波浪进度球

    这段时间项目做完了 本以为可以偷懒一段时间 结果领导又接了一个车载项目让我做 很气但是没办法 还是得搞 谁让我是搬砖的呢 今天搞了一个水波纹的自定义控件 先看效果 第一眼还是觉得可以看的 其实我觉得有点丑 ui妹子说挺好看 好吧 那就这样吧
  • 【设计经验】5、Verilog对数据进行四舍五入(round)与饱和(saturation)截位

    原文链接 https www cnblogs com liujinggang p 10549095 html
  • 浅谈chrony服务

    浅谈chrony服务 chrony概念 Chrony 是 NTP 客户端的替代品 Chrony 的优势 更快的同步只需要数分钟而非数小时时间 从而最大程度减少了时间和频率 误差 对于并非全天 24 小时运行的虚拟计算机而言非常有用 能够更好
  • 图的m着色问题——回溯法及其优化(变量排序MRV, 值排序MCV, 前向检查ForwardChecking, 智能回溯, 边相容,K阶相容)python C++实现

    文章目录 图的m着色问题背景 背景知识 问题描述 回溯法的原理及其实现 回溯法基本思想 朴素回溯法解决图的m着色问题 回溯优化策略 回溯法优化 变量排序MRV 回溯法优化 值排序MCV 回溯法优化 前向检查ForwardChecking 边
  • [Transformer]TNASP: A Transformer-based NAS Predictor with a Self-evolution Framework

    TNASP 基于Transformer和自进化的的NAS Predictor Abstract Section I Introduction Section II Related Work Training based network pe
  • C++11-14 第5讲 Uniform Initialization 一致初始化值 &initializer_list

    版权说明 本博文属于个人笔记 本人保留对本文的所有权益 未经许可不得以任何形式转载 Uniform Initialization 一致初始化值 新手困惑初始化怎么写 可能发生在 中 任何初始化都用共通写法 旧 Rect r1 1 2 3 R
  • 6.3.3法线贴图

    1 法线贴图必须与灯光同时进行 2 从法线纹理取得模型空间的法线 再根据切线空间到世界空间的变换矩阵 传递到世界坐标系的法线 再进行计算
  • 和你一起draw9patch

    前言 在工作当中 你总会遇到制作点9图片的时候 我就在公司的新项目中遇到了 很多人说 这交给UI妹妹做就好了 为啥要烦劳我们自己动手 第一呢 作为程序员的我们 多学点东西是没错的 第二呢 UI妹妹做的点9图片产生的效果不是你想要的 一 制作
  • 小程序如何使用vant

    小程序如何使用vant 使用 Vant Weapp 前我强烈的建议大家去看下微信官方的 小程序简易教程 和 自定义组件介绍 点击下方超链接 https youzan github io vant weapp quickstart 第一步 首
  • 目标检测入门概念知识

    一个常见的目标检测网络 其本身往往可以分为一下三大块 Backbone network 即主干网络 目标检测网络的主体结构 是目标检测网络最为核心的部分 大多数时候 backbone选择的好坏 对检测性能影响是十分巨大的 代表网络有 VGG
  • ORB_SLAM2特征匹配

    ORB SLAM2特征匹配 SearchByProjection 使用于运动模型跟踪 函数原型 函数简介 知识难点 由两帧绝对位姿推出两帧相对位姿 前进与后退对搜索范围的影响 描述子的比较 方向一致性检测 运用于局部地图跟踪 函数原型 函数
  • 注解处理器APT在java中的实现

    概念理解 APT 英文全名 Annotation Processor Tool 即 注解处理器 它是 javac 的一个工具 这是Sun为了帮助注解的处理过程而提供的工具 apt被设计为操作Java源文件 而不是编译后的类 作用阶段示意图如
  • 正则表达式使用文档

    通过网站 https regex101 com 可以测试正则表达式的匹配结果及匹配过程 本文章抛开各个编程语言实现差异 仅做正则本身的介绍 会尽量将正则这玩意说明白 使得你看完这边文章后对正则基本可以运用自如 温馨提示 这篇文章会比较长 大
  • Nginx php 错误日志排查

    遇到错误 通常解决流程如下 比如一个php存储服务器的文件上传问题 px ef grep php fpm 查看fpm 是否启动 查看 fpm 运行用户以及权限 发现运行用户为 nobody 组 nobody 文件写入权限为 root cho
  • logPath_IS_UNDEFINED

    logPath IS UNDEFINED 解决Springboot项目启动的时候日志文件找不到路径新建文件夹的问题 网上也有很多案例 大部分都是路径没正确引入 或者引入springCloud依赖 在bootstrap yml配置 今天自己摸
  • 移动web开发基础

    目录 移动web开发 浏览器现状 PC 端常见浏览器 移动端常用浏览器 手机屏幕现状 常用移动端屏幕尺寸 移动端调用方式 总结 视口 1 布局视口 layout viewport 2 视觉视口 visual viewport 3 理想视口
  • C51语句概念

    C51语句概念 单分支语句 表达语句 if 表达式 分支一 else 分支二 表达语句 if 表达式 语句 include
  • mybatis怎么实现 FULL JOIN?

    问题 今天写查询的时候 遇到了一个难题 两个查询出来的表 可能左边的表里有这个类型的数据 右表里面没有 但是我也要把它查出来 右表有的 左表没有的也要显示出来 经过我的一番探索 找了 FULL JOIN 全连接 sql中很简单 有关键字 但
  • 靶场练习之Lampiao

    一 环境搭建 lampiao靶场下载地址 Lampi o 1 VulnHub 使用vm打开 配置kali和靶场在同一个网络 建议都为net连接 二 信息收集 1 nmap扫描 使用nmap扫描整个网段 找到靶机的ip地址 nmap sS P
  • 释伴:Linux 上的 Shebang 符号(#!)

    使用类Unix系统的同学可能都对 这个符号并不陌生 但是你真的了解它吗 这个符号的名称 叫做 Shebang 或者 Sha bang 长期以来 Shebang都没有正式的中文名称 Linux中国翻译组的GOLinux将其翻译为 释伴 即 解