歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux命令 >> 開發 Linux 命令行實用程序

開發 Linux 命令行實用程序

日期:2017/2/28 10:05:29   编辑:Linux命令
Linux命令
  最佳實踐和考慮周全的編碼造就可靠的命令行工具
  
  本文將指導您學習如何編寫即使對最終用戶而言也足夠簡單的 Linux 命令行實用程序。本文以概述可靠的命令行最佳實踐開始,並以詳細地研究一個有效的選頁工具結束,為您提供動手編寫自己的實用程序所需要的背景知識。
  本文演示如何編寫與 cat、ls、pr 和 mv 等標准命令類似的 Linux 命令行實用程序。我選擇了一個名為 selpg 的實用程序,這個名稱代表 SELect PaGes。selpg 允許用戶指定從輸入文本抽取的頁的范圍,這些輸入文本可以來自文件或另一個進程。selpg 是以在 Linux 中創建命令的事實上的約定為模型創建的,這些約定包括:
  
  獨立工作
  在命令管道中作為組件工作(通過讀取標准輸入或文件名參數,以及寫至標准輸出和標准錯誤)
  接受修改其行為的命令行選項
  不久前我為一位客戶開發了 selpg。隨後我將它公布在一個 UNIX 郵件列表上,結果有許多成員告訴我他們發現這是一個有用的工具。
  
  該實用程序從標准輸入或從作為命令行參數給出的文件名讀取文本輸入。它允許用戶指定來自該輸入並隨後將被輸出的頁面范圍。例如,如果輸入含有 100 頁,則用戶可指定只打印第 35 至 65 頁。這種特性有實際價值,因為在打印機上打印選定的頁面避免了浪費紙張。另一個示例是,原始文件很大而且以前已打印過,但某些頁面由於打印機卡住或其它原因而沒有被正確打印。在這樣的情況下,則可用該工具來只打印需要打印的頁面。
  
  除了包含 Linux 實用程序現實的示例外,本文還有以下特性:
  
  它用實例說明了 Linux 軟件開發環境的能力。
  它演示了對一些系統調用和 C 庫函數的適當使用,其中包括 fopen、fclose、access、setvbuf、perror、strerror 和 popen。
  它實現了打算用於通用目的的實用程序(而不是一次性程序)所應有的那種徹底的錯誤檢查。
  它對潛在的問題提出警告,如在 C 中編程時可能出現的緩沖區溢出,並就如何預防這些問題提供了建議。
  它演示了如何進行手工編碼的命令行參數解析。
  它演示了如何在管道中以及在輸入、輸出和錯誤流重定向的情況下使用該工具。
  命令行准則
  通用 Linux 實用程序的編寫者應該在代碼中遵守某些准則。這些准則經過了長期發展,它們有助於確保用戶以更靈活的方式使用實用程序,特別是在與其它命令(內置的或用戶編寫的)以及 shell 的協作方面 — 這種協作是利用 Linux 作為開發環境的能力的手段之一。selpg 實用程序用實例說明了下面列出的所有准則和特性。(注:在接下來的那些示例中,“$”符號代表 shell 提示符,不必輸入它。)
  
  准則 1. 輸入
  應該允許輸入來自以下兩種方式:
  
  在命令行上指定的文件名。例如:
  
  $ command input_file
  
  在這個例子中,command 應該讀取文件 input_file。
  
  標准輸入(stdin),缺省情況下為終端(也就是用戶的鍵盤)。例如:
  
  $ command
  
  這裡,用戶輸入 Control-D(文件結束指示符)前輸入的所有內容都成為 command 的輸入。
  
  但是,使用 shell 操作符“<”(重定向標准輸入),也可將標准輸入重定向為來自文件,如下所示:
  
  
  $ command < input_file
  
  這裡,command 會讀它的標准輸入,不過 shell/內核已將其重定向,所以標准輸入來自 input_file。
  
  使用 shell 操作符“|”(pipe)也可以使標准輸入來自另一個程序的標准輸出,如下所示:
  
  
  $ other_command | command
  
  這裡,other_command 的標准輸出(stdout)被 shell/內核透明地傳遞至 command 的標准輸入。
  
  准則 2. 輸出
  輸出應該被寫至標准輸出,缺省情況下標准輸出同樣也是終端(也就是用戶的屏幕):
  
  
  $ command
  
  在這個例子中,command 的輸出出現在屏幕上。
  
  同樣,使用 shell 操作符“>”(重定向標准輸出)可以將標准輸出重定向至文件。
  
  
  $ command > output_file
  
  這裡,command 仍然寫至它的標准輸出,不過 shell/內核將其重定向,所以輸出寫至 output_file。
  
  或者,還是使用“|”操作符,command 的輸出可以成為另一個程序的標准輸入,如下所示:
  
  
  $ command | other_command
  
  在這個例子中,shell/內核安排 command 的輸出成為 other_command 的輸入。
  
  准則 3. 錯誤輸出
  錯誤輸出應該被寫至標准錯誤(stderr),缺省情況下標准錯誤同樣也是終端(也就是用戶的屏幕):
  
  
  $ command
  
  這裡,運行 command 時出現的任何錯誤消息都將被寫至屏幕。
  
  但是使用標准錯誤重定向,也可以將錯誤重定向至文件。例如:
  
  
  $ command 2>error_file
  
  在這個例子中,command 的正常輸出在屏幕顯示,而任何錯誤消息都被寫至 error_file。
  
  可以將標准輸出和標准錯誤都重定向至不同的文件,如下所示:
  
  
  $ command >output_file 2>error_file
  
  這裡,將標准輸出寫至 output_file,而將所有寫至標准錯誤的內容都寫至 error_file。
  
  如果已將標准輸出重定向至某一位置,也可以將標准錯誤重定向至同一位置。例如:
  
  
  $ command 2>&1
  
  在這個例子中,符號“2>&1”表示“將標准錯誤發送至標准輸出被重定向的任何位置”,因此錯誤和正常的消息都將在屏幕上顯示。當然,這是多余的,因為下面簡單的調用
  
  
  $ command
  
  將做同樣的事。在標准輸出已被重定向至其它源,而您希望在同一命令行上將標准錯誤也寫至同一目的地時,該特性就非常有用。例如:
  
  
  $ command >output_file 2>&1
  
  在這個例子中,已首先將標准輸出重定向至 output_file;因此“2>&1”將使標准錯誤也被重定向至 output_file。
  
  准則 4. 執行
  程序應該有可能既獨立運行,也可以作為管道的一部分運行,如上面的示例所示。該特性可以重新敘述如下:不管程序的輸入源(文件、管道或終端)和輸出目的地是什麼,程序都應該以同樣的方式工作。這使得在如何使用它方面有最大的靈活性。
  
  准則 5. 命令行參數
  如果程序可以根據其輸入或用戶的首選參數有不同的行為,則應將它編寫為接受名為選項的命令行參數,這些參數允許用戶指定什麼行為將用於這個調用。
  
  作為選項的命令行參數由前綴“-”(連字符)標識。另一類參數是那些不是選項的參數,也就是說,它們並不真正更改程序的行為,而更象是數據名稱。通常,這類參數代表程序要處理的文件名,但也並非一定如此;參數也可以代表其它東西,如打印目的地或作業標識(有關的示例,請參閱“man cancel”)。
  
  可能代表文件名或其它任何東西的非選項參數(那些沒有連字符作為前綴的)如果出現的話,應該在命令的最後出現。
  
  通常,如果指定了文件名參數,則程序把它作為輸入。否則程序從標准輸入進行讀取。
  
  所有選項都應以“-”(連字符)開頭。選項可以附加參數。
  
  Linux 實用程序語法圖看起來如下:
  
  
  $ command mandatory_opts [ optional_opts ] [ other_args ]
  
  其中:
  
  command 是命令本身的名稱。
  mandatory_opts 是為使命令正常工作必須出現的選項列表。
  optional_opts 是可指定也可不指定的選項列表,這由用戶來選擇;但是,其中一些參數可能是互斥的,如同 selpg 的“-f”和“-l”選項的情況(詳情見下文)。
  other_args 是命令要處理的其它參數的列表;這可以是任何東西,而不僅僅是文件名。
  在以上定義中,術語“選項列表”是指由空格、跳格或二者的結合所分隔的一系列選項。
  
  以上在方括號中顯示的語法部分可以省去(在此情況下,必須將括號也省去)。
  
  各個選項看起來可能與下面相似:
  
  
  -f (單個選項)
  -s20 (帶附加參數的選項)
  -e30 (帶附加參數的選項)
  -l66 (帶附加參數的選項)
  
  有些實用程序對帶參數的選項采取略微不同的格式,其中參數與選項由空格分隔 — 例如,“-s 20” — 但我沒有選擇這麼做,因為它會使編碼復雜化;這樣做的唯一好處是使命令易讀一些。
  
  以上是 selpg 支持的實際選項。
  
  selpg 程序邏輯
  如前面所說的那樣,selpg 是從文本輸入選擇頁范圍的實用程序。該輸入可以來自作為最後一個命令行參數指定的文件,在沒有給出文件名參數時也可以來自標准輸入。
  
  selpg 首先處理所有的命令行參數。在掃描了所有的選項參數(也就是那些以連字符為前綴的參數)後,如果 selpg 發現還有一個參數,則它會接受該參數為輸入文件的名稱並嘗試打開它以進行讀取。如果沒有其它參數,則 selpg 假定輸入來自標准輸入。
  
  參數處理
  
  
  “-sNumber”和“-eNumber”強制選項:
  selpg 要求用戶用兩個命令行參數“-sNumber”(例如,“-s10”表示從第 10 頁開始)和“-eNumber”(例如,“-e20”表示在第 20 頁結束)指定要抽取的頁面范圍的起始頁和結束頁。selpg 對所給的頁號進行合理性檢查;換句話說,它會檢查兩個數字是否為有效的正整數以及結束頁是否
Copyright © Linux教程網 All Rights Reserved