Bash Shebang 小结
在 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 写法
如果只考虑在单一的系统中执行,足够了。
Bash Shebang 小结的更多相关文章
- bash操作小结
刚开始学写bash脚本,发现有很多需要注意的细节问题,在这里记录一下便于记忆: 1. help test 帮助 2. bash提供的数组数据结构,它是以数字为下标的,和C语言从0开始的下一样 参考 ...
- bash学习记录
bash: 管理员: 提示符# 普通用户:提示符$ 环境变量 A=3(变量是指内存空间,A指的是内存空间的名称-变量标示符) PS1 \u@\h:\w\$ \u用户名 \h主机名 \w工作目录的 ...
- WebStorm换主题(护眼)
一.下载喜欢颜色的主题 http://www.phpstorm-themes.com/ 我用的豆沙绿护眼 <scheme name="Solarized Light My" ...
- linux shell攻略学习笔记一 基础篇
1.#!/bin/bash shebang 可以自定义 比如 #!/bin/bash +x 就会打印出执行日志 linux中 \ 代表null \n2\n3” 会转义其中的\n,生成3行数据 $! 保 ...
- Linux 下如何隐藏自己不被发现?
可能在某些情况下,自己运行的程序不想或者不方便被其他人看到,就需要隐藏运行的进程.或者某些攻击者采用了本文介绍的隐藏技术,也可以让大家看到如何进行对抗. 隐藏有两种方法: kernel 层面,不对用户 ...
- Linux Shell 学习笔记 00
1.Bash = Bourne Again SHell 2.终端提示符: #普通用户 username@hostname$ #管理员用户 root@hostname# 3.shell脚本通常是一个以s ...
- BASH 命令以及使用方法小结【转】
1,export VAR=... 这个命令在Shell下直接运行可以使之后运行的脚本也知道这个VAR.但是如果 这个命令在脚本中运行,那么不影响脚本以外的参数.举个例子,如果在一个脚本运行之前没有 V ...
- linux bash & profile &bash_profile 小结
login 方式:: su - oracle 依次 /etc/bash.bashrc———— /home/$user/.bashrc ———— /ect/profile ———— /home/$use ...
- BASH 命令以及使用方法小结
最近工作中需要写一个Linux脚本,用到了很多BASH命令,为了防止以后忘记,在这里把它们一一记下来.可能会比较乱,随便看看就好了.如果有说的不对的地方也欢迎大家指正. 1,export VAR=.. ...
随机推荐
- puppeteer入门
转自: https://www.jianshu.com/p/a89d8d6c007b 作者: ppCode puppeteer新手入门(chromium下载跳坑) ppCode 关注 2017.12. ...
- Apache POI导出excel表格
项目中我们经常用到导出功能,将数据导出以便于审查和统计等.本文主要使用Apache POI实现导出数据. POI中文文档 简介 ApachePOI是Apache软件基金会的开放源码函式库,POI提供A ...
- [20180614]删除bootstrap$记录无法启动2.txt
[20180614]删除bootstrap$记录无法启动2.txt --//前几天看链接http://www.xifenfei.com/2018/05/willfully-delete-bootstr ...
- linux设置自动更换壁纸
#!/bin/bash let n=0 files=($HOME/wallpapers/*.jpg) count=${#files[@]} while [ 1 ] do let "n=n%$ ...
- SQL SERVER2008判断文件夹是否存在并创建文件夹
原文地址:https://www.cnblogs.com/iiwen/p/7650118.html DECLARE @PATH VARCHAR(255) --路径 DECLARE @DATE VARC ...
- linux E325: 注意 发现交换文件 "*.swp" 解决方法
今天在linux里修改脚本文件时,不小心非正常关闭了脚本文件,再次编辑时,每次都提示 如下错误: E325: 注意发现交换文件 ".bqh.sh.swp" 所有者: root 日期 ...
- January 31st, 2018 Week 05th Wednesday
Real love is not just instinct, but intent. 真正的爱不是身体上的一见钟情,而是要用心去经营. What is real love? Honestly, I ...
- 怎么配置 Oracle 侦听器来使用SQL操作ST_Geometry
关于这个内容,其实从ArcSDE9.2推出ST_Geometry就让用户感到很有吸引力,而且特别是在ArcSDE9.3之后,用户使用SQL操作ST_geometry越来越多,但是在配置Oracle监听 ...
- File类_常见的方法(获取目录中指定规则的内容)
首先定义过滤器 import java.io.File; import java.io.FilenameFilter; public class FileByJava implements Filen ...
- C#接口的显隐实现
显示接口实现与隐式接口实现 何为显式接口实现.隐式接口实现?简单概括,使用接口名作为方法名的前缀,这称为“显式接口实现”:传统的实现方式,称为“隐式接口实现”.下面给个例子. IChineseGree ...