天天看點

《UNIX程式設計環境》——5.7 pick指令:空格和參數

本節書摘來自異步社群《unix程式設計環境》一書中的第5章,第5.7節,作者:【美】brian w. kernighan , rob pike著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

我們已經接觸了書寫shell的pick指令需要的多數指令。我們隻需要一種新的機制來接收使用者輸入。shell内部指令read提供了這一功能,即從标準輸入讀一行正文,并把讀到的文本(不含換行)賦給命名變量:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

read最常用于注冊時在.profile檔案裡設定環境,主要是建立shell環境變量,如term。

read隻能讀取标準輸入,而且不能被重定向。shell内部指令(與控制流原語不同,如for)都不能使用>或<重定向:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

這也許可以說是shell的一個缺陷,但這就是現實。幸運的是,重定向read外圍的循環可以達到同樣的目的。這是pick指令實作的關鍵:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

echo-n抑制最後一個換行符,是以使用者的響應可以列印在提示符的同一行。當然,提示符列印在/dev/tty上,因為這裡的标準輸出絕大多數情形下并不是終端。

break語句取自c語言,表示終止内部循環。上例中,輸入q鍵時終止for循環。q為quit的縮寫,易用,這一退出響應幾乎已成為慣例,其他很多程式也采用q。

pick指令行參數裡的空格是很有趣的:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

要觀察pick程式如何讀取參數,運作pick并在每次提示符出現後按Enter鍵。程式工作情況很好:for i适當地處理參數。我們還可以用其他方法寫循環:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

這種方式不能成功,因為循環中的操作數被重複掃描,這樣第一個參數中的空格符将它變成兩個參數。嘗試使用引号包覆參數$*:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

還是不能正常工作,因為“$*”是由空格符分隔的所有參數連在一起構成的單個詞。

可能的解決辦法是,shell對字元串“$@”作特殊處理,并将它轉換為嚴格的shell檔案參數:

《UNIX程式設計環境》——5.7 pick指令:空格和參數

如果不用引号包覆$@,它與$*相同;$@隻有用雙引号包覆時才具有特殊性質。我們在overwrite程式中用它來保護使用者的指令參數。

上述内容可以歸納為如下規則。

$*和$@擴充為參數,并被重複掃描;參數的空格符将字元串分成多個參數。

 “$*”表示shell檔案的所有參數及其空格符連在一起作為單個詞處理。

 “$@”與shell檔案接收的參數等價,參數中的空格被忽略,其結果是等同于原來參數的一個單詞清單。

如果pick程式沒有參數,可以讀取标準輸入,是以可以使用指令

《UNIX程式設計環境》——5.7 pick指令:空格和參數

這裡我們不研究這個版本的pick:它的複雜度和難以了解的程度遠遠超過下一章将要介紹的用c語言編寫的程式。

下面練習中的前兩個題目比較難,屬于進階shell程式員教程的内容。

練習5-24 寫一個pick程式,當指令行中沒有參數支援時它從标準輸入讀取參數。程式應能正确處理空格符。能否處理q響應?如果不能,試做下一個練習。

練習5-25 雖然shell的内部指令如read和sed不能重定向,但shell本身可以暫時重定向。閱讀sh(1)節中對exec指令的描述,考慮如果不調用子shell如何将read定向到/dev/tty。(可以先參閱第7章。)

練習5-26(比較容易) 在.profile檔案裡使用read初始化term和其他相關參數,如tab停止位。

繼續閱讀