1. 程式人生 > >【轉】什麽是“腳本語言”

【轉】什麽是“腳本語言”

perl 一個 系統類型 解釋 大型 就是 編譯性語言 java 補丁

很多人都會用一些“腳本語言”(scripting language),卻很少有人真正的知道到底什麽是腳本語言。很多人用 shell 寫一些“腳本”來完成日常的任務,用 Perl 或者 sed 來處理一些文本文件,很多公司用“腳本”來跑它們的“build”(叫做 build script)。那麽,到底什麽是“腳本語言”與“非腳本語言”的區別呢?

其實“腳本語言”與“非腳本語言”並沒有語義上,或者執行方式上的區別。它們的區別只在於它們設計的初衷:腳本語言的設計,往往是作為一種臨時的“補丁”。它的設計者並沒有考慮把它作為一種“通用程序語言”,沒有考慮用它構建大型的軟件。這些設計者往往沒有經過系統的訓練,有些甚至連最基本的程序語言概念都沒搞清楚。相反,“非腳本”的通用程序語言,往往由經過嚴格訓練的專家甚至一個小組的專家設計,它們從一開頭就考慮到了“通用性”,以及在大型工程中的可靠性和可擴展性。

首先我們來看看“腳本”這個概念是如何產生的。使用 Unix 系統的人都會敲入一些命令,而命令貌似都是“一次性”或者“可拋棄”的。然而不久,人們就發現這些命令其實並不是那麽的“一次性”,自己其實一直在重復的敲入類似的命令,所以有人就發明了“腳本”這東西。它的設計初衷是“批量式”的執行命令,你在一個文件裏把命令都寫進去,然後執行這個文件。可是不久人們就發現,這些命令行其實可以用更加聰明的方法構造,比如定義一些變量,或者根據系統類型的不同執行不同的命令。於是,人們為這腳本語言加入了變量,條件語句,數組,等等構造。“腳本語言”就這樣產生了。

然而人們卻沒有發現,其實他們根本就不需要腳本語言。因為腳本語言裏面的這些結構,在任何一種“嚴肅”的程序語言(比如 Java,Scheme)裏面,早就已經存在了,而且設計得更加完善。所以腳本語言往往是在重新發明輪子,甚至連輪子都設計不好。早期腳本語言的“優勢”,也許只在於它不需要事先“編譯”,它“調用程序”的時候,貌似可以少打幾個字。腳本語言對於 C 這樣的語言,也許有一定的價值。然而,如果跟 Scheme 或者 Java 這樣的語言來比,這個優勢就非常不明顯了。比如,你完全可以想一個自動的辦法,寫了 Java 代碼之後,先調用 Java 編譯器,然後調用 JVM,最後刪掉 class 文件。或者你可以選擇一種有解釋執行方式的“嚴肅語言”,比如 Scheme。

很多人把 Scheme 誤稱為“腳本語言”,就是因為它像腳本語言一樣可以解釋執行,然而 Scheme 其實是比 C 和 Java 還要“嚴肅”的語言。Scheme 從一開頭就被設計為一種“通用程序語言”,而不是用來進行某種單一簡單的任務。Scheme 的設計者比Java 的設計者造詣更加深厚,所以他們對 Java 的一些設計錯誤看得非常清楚。像 Chez Scheme 這樣的編譯器,其實早就可以把 Scheme 編譯成高效的機器代碼。實際上,很多 Scheme 解釋器也會進行一定程度的“編譯”,有些編譯為字節碼,有些編譯為機器代碼,然後再執行。所以在這種情況下,通常人們所謂的“編譯性語言”與“解釋性語言”,幾乎沒有本質上的區別,因為你看到的“解釋器”,不過是自動的先編譯再執行。

跟 Java 或者 Scheme 這樣的語言截然不同,“腳本語言”往往意味著異常拙劣的設計,它的設計初衷往往是目光短淺的。這些語言裏面充滿了歷史遺留下來的各種臨時的 hack,幾乎沒有“原則”可言。Unix 的 shell(比如 bash,csh,……),一般都是這樣的語言。Java 的設計也有很多問題,但也跟“腳本語言”有天壤之別。然而,在當今現實的工程項目中,腳本語言卻占據了它們不該占有的地位。例如很多公司使用 shell 腳本來處理整個軟件的“build”過程或者測試過程,其實是相當錯誤的決定。因為一旦這種 shell 腳本日益擴展,就變得非常難以控制。經常出現一些莫名其妙的問題,卻很難找到問題的所在。Linux 使用 shell 腳本來管理很多啟動項目,系統配置等等,其實也是一個歷史遺留錯誤。所以,不要因為看到 Linux 用那麽多 shell 腳本就認為 shell 語言是什麽好東西。

如果你在 shell 腳本裏使用通常的程序設計技巧,比如函數等,那麽寫幾百行的腳本還不至於到達不可收拾的地步。可是我發現,很多人頭腦裏清晰的程序設計原則,一遇到“寫腳本”這樣的任務就完全崩潰了似的,他們仿佛認為寫腳本就是應該“松散”一些。很多平時寫非常聰明的程序的人,到了需要處理“系統管理”任務的時候,就開始寫一些 shell 腳本,或者 Perl 腳本。他們寫這些腳本的時候,往往完全的忘記了程序設計的基本原則,例如“模塊化”,“抽象”等等。他們大量的使用“環境變量”一類的東西來傳遞信息,他們忘記了使用函數,他們到處打一些臨時性的補丁,只求當時不出問題就好。到後來,他們開始耗費大量的時間來處理腳本帶來的麻煩,卻始終沒有發現問題的罪魁禍首,其實是他們錯誤的認為自己需要“腳本語言”,然後認為寫腳本的時候就是應該隨便一點。

所以我認為腳本語言是一個禍害,它幾乎永遠是錯誤的決定。我們應該盡一切可能避免使用腳本語言。在沒有辦法的情況下(比如老板要求),也應該在腳本裏面盡可能的使用通常的程序設計原則。

【轉】什麽是“腳本語言”