注意:解释器需在开头第一行指定
#!
注释的是加载器(解释器)的路径, 比如: #!/bin/bash
就是说把脚本中的代码指令都传递给/bin/bash
:bin目录中的bash解释器来执行。
mac:~ user01$ cd /bin
mac:~ user01$ ls
[ df launchctl pwd test
bash domainname link rm unlink
cat echo ln rmdir wait4path
chmod ed ls sh zsh
cp expr mkdir sleep
csh hostname mv stty
date kill pax sync
dd ksh ps tcsh
除了使用 #!/bin/bash
外,大部分的脚本中都习惯使用#!/usr/bin/env
来指定路径。
那么,env到底有什么用呢?
先结合实际使用中遇到的问题看看:
脚本解释器在linux中可能被安装于不同的目录,或者同一个软件(比如Python、perl)安装有多个版本:
mac:~ user01$ which python
/usr/bin/python
mac:~ user01$ which python3
/usr/local/bin/python3
mac:~ user01$ which -a perl
/root/perl5/perlbrew/perls/perl-5.26.1/bin/perl
/usr/bin/perl
- python2版本和python3不仅目录不同,还因为不兼容的问题使用的解释器名称也不相同,python表示版本2,python3表示版本3以上。
到底执行哪一个解释器,取决于PATH
环境变量内路径的排列顺序:
mac:~ user01$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
在PATH
环境中,如果要使用perl
显然优先执行的是/root/perl5/...
目录下的perl-5.26.1版本。但是如果想要执行一个程序在perl-5.26.1以下版本运行,就可以使用:
mac:~ user01$ env PATH=/usr/bin perl xxx.pl
指定解释器路径的方式来执行perl脚本。
综合上述说明:
env是一个指令,可以指定解释器的具体路径,如果不指定具体路径,那么将根据PATH
环境变量中的目录顺序去查找。同时,env还规定一些系统环境变量。
mac:~ user01$ env
TERM_PROGRAM=Apple_Terminal
SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/zd/cw9zr66d65xcx_ylk5bkm1240000gn/T/
TERM_PROGRAM_VERSION=404.1
...... 省略很多 ......
实际开发中如果直接将解释器路径写死在脚本里#!/usr/bin/perl
,可能在某些系统就会出现找不到解释器而造成的兼容性问题。这时就可以通过env指令来解决这个问题:
示例: #!/usr/bin/env -S-P/usr/local/bin:/usr/bin:${PATH} perl
这种写法可以让你的脚本在不同的系统上都能适用。 env会在/usr/local/bin
、/usr/bin
、${PATH}
这2+N个目录(${PATH}表示PATH环境变量中定义的目录)中寻找perl来执行的。
-S-P参数解释:
-P参数:指定一些目录去寻找perl这个程序,
#!/usr/bin/env -P/usr/local/bin:/usr/bin perl
的作用就是指定在/usr/local/bin和/usr/bin目录下寻找perl。
为了让程序更加的有可扩展性,可以写成
#!/usr/bin/env -S-P/usr/local/bin:/usr/bin:${PATH} perl
,那么它除了在这两个目录寻找之外,还会在PATH变量中定义的目录中寻找。