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=.. ...
随机推荐
- ionic入门
ionic安装 Ionic开发是依赖于Nodejs环境的,所以在开发之前我们需要安装好Nodejs.下载安装:http://nodejs.org/安装完成之后打开PowerShell输入命令node ...
- Linux远程访问及控制(SSH)
1.ssh协议:用于远程登录,端口号:22/tcp 配置文件: 1)服务器端口:/etc/ssh/sshd_config 2)客户端 :/etc/ssh/ssh_config 2.服务器监听选项: U ...
- tkinter内嵌Matplotlib系列(二)之函数曲线绘制
目录 目录 前言 (一)对matplotlib画布的封装: (二)思路分析: 1.需求说明: 2.框架的设置: 3.文件说明: (三)各文件的源代码 1.main.py 2.widget.py 3.f ...
- Unity3d Platformer Pro 2D游戏开发框架使用教程
前言 Platformer Pro框架是Unity3d AssetStore上一个非常强大和受欢迎的2d游戏开发框架,这个教程的大部分翻译于官方文档,一部分是工作总结,还有一部分是视频教程文档化.这个 ...
- 4、爬虫之mongodb
mongodb 简介 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品 ...
- Spring 自动清除缓存的配置
- spring.resources.chain.strategy.content.enabled=true - spring.resources.chain.strategy.content.pat ...
- vue+webpack安装sass过程中遇到权限不够,直接删除node_modus文件夹重新安装,node_modus先取得管理员权限才能删
vue vue-style-loader !css-loader错误 最近在学习vue框架,使用webpack打包vue项目,在执行npm run start的时候 出现如下错误: This depe ...
- File类_常见的方法(获取系统根目录与指定目录的容量)
获取系统根目录 import java.io.File; public class File_ListRoots { public static void main(String[] args) { ...
- python五十六课——正则表达式(常用函数之match)
函数:match(regex,string,[flags=0])参数:regex:就是正则表达式(定义了一套验证规则)string:需要被验证的字符串数据flags:模式/标志位,默认情况下(不定义) ...
- Coprime (单色三角形+莫比乌斯反演(数论容斥))
这道题,先说一下单色三角形吧,推荐一篇noip的论文<国家集训队2003论文集许智磊> 链接:https://wenku.baidu.com/view/e87725c52cc58bd631 ...