在 shell(Bash 是一种 shell) 中执行外部程序和脚本时,Linux 内核会启动一个新的进程,以便在新的进程中执行指定的程序或脚本。内核知道该如何为编译型的程序做这件事,但是对于脚本程序呢?当 shell 要求内核执行一个脚本文件时,内核是不知道该怎么办的!所以它回应一个 "not executable format file" 的错误消息。Shell 收到这样的消息后会做出类似下面的判断:这不是个编译型程序,那它肯定是一个 shell 脚本;接着就启动一个新的 /bin/sh 副本来这些该程序。

当系统中只有一个 shell(/bin/sh) 时这并没有什么问题。但是当前的系统中一般都存在多个 shell,比如 Bash、Dash等等。因此需要通过一种方式,告诉 Linux 内核应该以哪个 shell 来执行指定的脚本。实时上,这么做有助于执行机制的通用化,让用户可以直接引用任何的程序语言解释器,而不仅仅是一个 shell。具体的方法是通过脚本文件中特殊的第一行来设置:在第一行的开头处使用 #! 这两个字符(英文一般称为 shebang)。

当一个脚本中第一行是以 #! 这两个字符开头时,内核会扫描该行的其余部分,看是否可以找到可以用来执行该脚本文件的解释器。所以这是一种非常通用的做法,因为除了 shell 我们还可以指定其它的解释器,比如:

#!/usr/bin/awk
# 这个脚本是一个 awk 程序

#!/bin/bash

直接指定 shell 的绝对路径是一种经典的写法。这样内核会直接调用你指定的解释器,并把脚本文件作为参数传递给它。这样做的缺点也非常明显,面对多如牛毛的 Linux 发行版,你无法保证所有系统中的 bash 程序都放置在 /bin 目录下。当然其它程序的路径就更无法保证了。

/usr/bin/env  命令

让我们先来了解一下 /usr/bin/env 命令的执行方式,比如下面的命令:

$ env name=value name2=value2 program args

这会使用环境变量和由 name=value 和 name2=value2 指定的值扩展当前环境而形成的环境运行命令 program args。如果不包含任何参数,比如 name=value,那么将传递不经过修改的当前环境。因为 env 是外部命令,所以它并不知道 bash 中的别名,env 只是将程序和参数传递给 exec 调用。

#!/usr/bin/env bash

在了解了 /usr/bin/env 命令之后,让我们来看看 shebang 的另一种写法:

#!/usr/bin/env bash

你会看到越来越多的脚本采用了这种写法。通过 /usr/bin/env 运行命令的好处是可以在当前环境中查找程序的默认版本。这样,就不必在系统上的特定位置查找它,因为这些路径在不同的系统中可能位于不同的位置。只要你指定的解释器程序在你的 PATH 变量中,这种写法就会找到它。当然,这么做的前提是 /usr/bin/env 必须存在。
这种写法也是有缺点的,比如我们可以创建一个名称为 bash 的程序,并把它的路径添加到 PATH 变量的靠前位置,这样就会使用你写的假 bash 程序来执行脚本,而不是真正的 bash 程序,这是一个安全隐患。

个人的理解

#!/usr/bin/env bash 写法
更灵活,可移植性较好,但是有安全风险。

#!/bin/bash 写法
如果只考虑在单一的系统中执行,足够了。

参考:
Shebang (Unix)

Bash Shebang 小结的更多相关文章

  1. bash操作小结

    刚开始学写bash脚本,发现有很多需要注意的细节问题,在这里记录一下便于记忆: 1. help test  帮助 2. bash提供的数组数据结构,它是以数字为下标的,和C语言从0开始的下一样  参考 ...

  2. bash学习记录

    bash: 管理员:  提示符# 普通用户:提示符$ 环境变量 A=3(变量是指内存空间,A指的是内存空间的名称-变量标示符) PS1  \u@\h:\w\$  \u用户名 \h主机名 \w工作目录的 ...

  3. WebStorm换主题(护眼)

    一.下载喜欢颜色的主题 http://www.phpstorm-themes.com/ 我用的豆沙绿护眼 <scheme name="Solarized Light My" ...

  4. linux shell攻略学习笔记一 基础篇

    1.#!/bin/bash shebang 可以自定义 比如 #!/bin/bash +x 就会打印出执行日志 linux中 \ 代表null \n2\n3” 会转义其中的\n,生成3行数据 $! 保 ...

  5. Linux 下如何隐藏自己不被发现?

    可能在某些情况下,自己运行的程序不想或者不方便被其他人看到,就需要隐藏运行的进程.或者某些攻击者采用了本文介绍的隐藏技术,也可以让大家看到如何进行对抗. 隐藏有两种方法: kernel 层面,不对用户 ...

  6. Linux Shell 学习笔记 00

    1.Bash = Bourne Again SHell 2.终端提示符: #普通用户 username@hostname$ #管理员用户 root@hostname# 3.shell脚本通常是一个以s ...

  7. BASH 命令以及使用方法小结【转】

    1,export VAR=... 这个命令在Shell下直接运行可以使之后运行的脚本也知道这个VAR.但是如果 这个命令在脚本中运行,那么不影响脚本以外的参数.举个例子,如果在一个脚本运行之前没有 V ...

  8. linux bash & profile &bash_profile 小结

    login 方式:: su - oracle 依次 /etc/bash.bashrc———— /home/$user/.bashrc ———— /ect/profile ———— /home/$use ...

  9. BASH 命令以及使用方法小结

    最近工作中需要写一个Linux脚本,用到了很多BASH命令,为了防止以后忘记,在这里把它们一一记下来.可能会比较乱,随便看看就好了.如果有说的不对的地方也欢迎大家指正. 1,export VAR=.. ...

随机推荐

  1. gitlab 和 github 配置 SSH Keys

    gitlab 文档上给了很好的配置的例子:https://gitlab.com/help/ssh/README#locating-an-existing-ssh-key-pair 针对mac 下的使用 ...

  2. Windows下cwrsync客户端与rsync群辉存储客户端数据同步

    cwRsync简介 cwRsync是Rsync在Windows上的实现版本,Rsync通过使用特定算法的文件传输技术,可以在网络上传输只修改了的文件. cwRsync主要用于Windows上的远程文件 ...

  3. Win10系统电脑桌面图标没有了怎么办

    win10系统相对来说还是有些不稳定的,有时候打开电脑会发现,桌面上的图标不见了,遇见这种情况,先别着急,可以使用两种很简单的方法来解决. 方法一: 在桌面上右键,点击查看,看“显示桌面图标”这一项前 ...

  4. 4.7 Sublime Text3 中配置 Python环境 --之上安装Sublime 3

    返回总目录 目录: 1.展示效果: 2.缺优分析: 3.下载Sublime Text3 (一)展示效果: 1.能够交互式编写Python代码: 2.可以编写文件式Python代码: 3.能够自动补齐代 ...

  5. element-ui使用导航栏跳转路由用法

    element-ui使用导航栏跳转路由用法 最近初学vue,试着做一个小项目熟悉语法与思想,其中使用elemen-ui的导航栏做路由跳转切换页面.下面记录一下学习过程 element-ui引入vue项 ...

  6. Android 怎样开启与关闭adb 的认证机制(google adb secure) (adb RSA 指纹认证)

    前言         欢迎大家我分享和推荐好用的代码段~~声明         欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net           ...

  7. Git命令的使用_操作远程仓库——详细教程3

    本博文讲述将本地仓库提交到GIT@OSC(或者是GitHub),故而需要用户首先有一个GIT@OSC(或者是GitHub)帐号. 我的GIT@OSC帐号是:https://git.oschina.ne ...

  8. centos断网调试

    保存命令 按ESC键 跳到命令模式,然后: :w 保存文件但不退出vi:w file 将修改另外保存到file中,不退出vi:w! 强制保存,不推出vi:wq 保存文件并退出vi:wq! 强制保存文件 ...

  9. 单节点etcd配置

    $ cat /etc/etcd/etcd.conf ETCD_DATA_DIR="/var/lib/etcd/default.etcd" #监听URL,用于与其他节点通讯 ETCD ...

  10. 第一行代码 -3-2 软件也要拼脸蛋-UI界面-更强大的滚动条-RecyclerView

    简述教程:https://www.jianshu.com/p/4fc6164e4709 一 基础准备 1 添加RecyclerView控件引用库文件 2 总布局添加RecyclerView控件 3 R ...