背??景在使用shell脚本或者Python脚本时,有些人喜欢用#!/usr/bin/envNAME来指定解析程序,而有些人则喜欢用#!/usr/bin/NAME,前者往往是used认为兼容性较好,优先使用。本文将仔细分析这种写法的优缺点。分析首先可以仔细阅读env命令的使用手册。这里我们只选择开头部分NAMEenv-runaprograminamodifiedenvironmentSYNOPSISenv[OPTION]...[-][NAME=VALUE]...[COMMAND[ARG]...]使用时可以看到env来指定你的解析程序,系统会在PATH环境变量中寻找对应的解析程序。当系统中存在不同的解析程序版本时,可以通过设置PATH环境变量来指定优先使用某个版本。另外,如果你的脚本将被移植到不同的系统,移植性会更好。然而,任何事情都有两个方面,使用#!/usr/bin/envNAME指定解析器也不例外。想象这样一种情况,你在系统中安装了一个名为program-a的解析程序,放在/directory-a目录下,然后修改系统环境变量PATH为:PATH=/directory-a:$PATH然后你使用#!/usr/bin/envprogram-a在脚本中指定解析程序,后来另一位同事不知不觉在这台服务器上安装了一个名为program-a的解析程序(版本不同,甚至功能也大相径庭),放到/directory-b下,修改PATH为:PATH=/directory-b:$PATH这样,如果你的脚本可能用错了解析器会失败。还有一种常见的情况。在linux中使用crontab命令添加周期性任务时,如果任务是自己写的脚本,并且在脚本中使用#!/usr/bin/envNAME指定解析器,也有出错的风险,因为crontab默认只使用非常有限的环境变量,可以使用cat/etc/crontab查看当前系统crontab的默认配置$cat/etc/crontabSHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=root#详情参见man4crontabs#作业定义示例:#.----------------minute(0-59)#|.------------小时(0-23)#||.------------月中的第几天(1-31)#|||.-------月(1-12)或一月、二月、三月、四月...#||||.----星期几(0-6)(星期日=0或7)或星期日、星期一、星期二、星期三、星期四、星期五、星期六#|||||#*****user-name要执行的命令这种情况下,如果你使用env指定你的分析程序,而这个分析程序正好不在crontab中如果是在配置的PATH环境变量的路径中,它可能会导致你的任务出错。综上所述,用#!/usr/bin/envNAME指定解析程序不一定好。你首先要考虑你的脚本运行的环境,是否会移植到其他系统,或者你的脚本是否会被crontab执行,你要注意你的分析程序是否在crontab的环境变量中。
