shell腳本之位於第一行的#!


 

當Shell執行一個程序時,會要求UNIX內核啟動一個新的進程(process),以便在該進程里執行所指定的程序。內核知道如何為編譯型程序做這件事。我們的nusers Shell腳本並非編譯型程序;當Shell要求內核執行它時,內核將無法做這件事,並回應“not executable format file”(不是可執行的格式文件)錯誤信息。Shell收到此錯誤信息時,就會說“啊哈,這不是編譯型程序,那么一定是Shell腳本”,接着會啟動一個新的 /bin/sh(標准Shell)副本來執行該程序。

 
    當系統只有一個Shell時,“退回到/bin/sh”的機制非常方便。但現行的UNIX系統都會擁有好幾個Shell,因此需要通過一種方式,告知UNIX內核應該以哪個Shell來執行所指定的Shell腳本。事實上,這么做有助於執行機制的通用化,讓用戶得以直接飲用任何的程序語言解釋器,而非只是一個命令Shell。方法是,通過腳本文件中特殊的第一行來設置:在第一行的開頭處使用#!這兩個字符。
 
    當一個文件中開頭的兩個字符是#!時,內核會掃描該行其余部分,看是否存在可用來執行程序的解釋器的完整路徑。(中間如果出現任何空白符號都會略過。)此外,內核還會掃描是否有一個選項要傳遞給解釋器。內核會以被指定的選項來引用解釋器,再搭配命令行的其他部分。舉例來說,假設有一個csh腳本(/bin/csh是C Shell的命令解釋器),名為/usr/ucb/whizprog,它的第一行如下所示:
        #! /bin/csh -f
 
    再者,如果Shell的查找路徑(后面會介紹)里有/usr/ucb,當用戶鍵入 whizprog -q /dev/tty01 這條命令,內核解釋#!這行后,便會以如下的方式來引用csh:
        /bin/csh -f /usr/ucb/whizprog -q /dev/tty01
 
    這樣的機制讓我們得以輕松地引用任何的解釋器。例如我們可以這樣引用獨立的awk程序:
        #! /bin/awk -f
        此處是awk程序
 
    Shell腳本通常一開始都是#! /bin/sh。如果你的 /bin/sh 並不符合POSIX標准,請將這個路徑改為符合POSIX標准的Shell。下面是幾個初級的陷阱(gotchas),請特別留意:
  • 當今的系統,對#!這一行的長度顯示從63到1024個字符(character)都有。請盡量不要超過64個字符
  • 在某些系統上,命令行部分(也就是要傳遞給解釋器執行的命令)包含了命令的完整路徑名稱。不過有些系統卻不是這樣;命令行的部分會原封不動地傳給程序。因此,腳本是否具有可移植性取決於是否有完整的路徑名稱。
  • 別在選項(option)之后放置任何空白,因為空白也會跟着選項一起傳遞給引用的程序。
  • 你需要知道解釋器的完整路徑明后才能。這樣可以用來規避可移植性問題,因為不同的廠商可能將同樣的東西放在不同的地方(例如 /bin/awk 和 /usr/bin/awk)。
  • 一些較舊的系統上,內核不具備解釋#!的能力,有些Shell會自行處理,這些Shell對於#!與緊隨其后的解釋器名稱之間是否可以有空白,可能是有不同的解釋。
 
    POSIX標准對#!的行為模式保留未定義(unspecified)狀態。此狀態是“只要一直保持POSIX兼容性,這是一個擴展功能”的標准說法。
 
    本系列接下來所有腳本開頭都會有#!行,下面是修訂過的nusers程序:
 
[many@avention my_sh]$ cat nusers
#! /bin/sh -
 
echo "開始統計用戶數..."
who | wc -l
echo "統計用戶數結束..."
 
    選項 - 表示沒有Shell選項;這是基於安全上的考慮,可以避免某種程度的欺騙式攻擊(spoofing attack)。
 
文章引用地址 https://www.cnblogs.com/avention/p/9661402.html
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM