在使用shell腳本或者Python腳本的時候,有的人喜歡使用#!/usr/bin/env NAME
指定解析程序,而有的人喜歡使用#!/usr/bin/NAME
,前者每每被認爲兼容性更好,因此應該優先使用,本文將仔細分析下這種寫法的利弊。shell
首先,能夠仔細看下env
命令的手冊,這裏咱們只節選開頭部分bash
NAME env - run a program in a modified environment SYNOPSIS env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
能夠看到,使用env
這種方式指定你的解析程序的時候,系統會在PATH環境變量中查找對應的解析程序,當系統中有不一樣的解析程序版本的時候能夠經過設置PATH環境變量的方式去指定優先使用某個版本,還有,若是你的腳本會被移植到不通的系統中去,可移植性也會更好。
可是,任何事物都有兩面性,使用#!/usr/bin/env NAME
去指定解析程序也不例外。
設想一種狀況,你在系統中安裝了一個名字叫program-a
的解析程序,放在了/directory-a
目錄下,而後將系統環境變量PATH
修改成:PATH=/directory-a:$PATH
而後你在腳本中使用#!/usr/bin/env program-a
指定解析程序,後面另外一位同事在不知情的狀況下,在這臺服務器上也安裝了一個叫作program-a
的解析程序(版本不一樣,或者更甚功能也有很大差別),放在了/directory-b
下,而且將PATH
修改成:PATH=/directory-b:$PATH
這樣的話若是你的腳本就有可能由於使用了錯誤的解析程序而失效。
還有一種常見的狀況,在Linux中使用crontab
命令添加週期性任務的時候,若是這個任務是本身寫的一個腳本,並且在腳本中使用了#!/usr/bin/env NAME
指定解析程序的話,也存在出錯的風險,由於crontab
默認只使用頗有限的環境變量,可使用cat /etc/crontab
查看當前系統中crontab
的默認配置服務器
$cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed
這樣的話,若是你使用env
指定你的解析程序,而這個解析程序又剛好不在crontab配置的PATH環境變量路徑中的話就有可能致使你的任務出錯。code
使用#!/usr/bin/env NAME
的方式指定解析程序並不必定是好的,你得先考慮清楚本身的腳本在什麼樣的環境中運行,會不會被移植到其它系統,或者你的腳本會被crontab
執行的話,就要注意本身的解析程序是否在crontab
的環境變量中。crontab