日期: Mon, 7 May 90 22:58:58 EDT
發信人: Alan Bawden
主題: cd ..: I am not making this up (cd ..: 這不是我編造出來的)
收信人: UNIX-HATERS
有什麼命令能比"cd"更直接了當的呢?讓我們看這個簡單的例子:"cd ftp"。如果我的當前目錄/home/ar/alan中有個子目錄叫做"ftp",那麼它就變成了我新的當前目錄,現在我在/home/ar/alan/ftp下了。簡單吧?
現在,你們知不知道"."和".."?每個目錄都會有兩個記錄:"."是指該目錄自己,".."是指父目錄。在上面的例子中,如果我想回到/home/ar/alan,只要敲"cd .."就可以了。
現在假設"ftp"是一個符號鏈接。假設它指向的是目錄/com/ftp/pub/alan。如果執行"cd
ftp",我的當前目錄將是/com/ftp/pub/alan。
和其他所有目錄一樣,/com/ftp/pub/alan也有一個叫".."的記錄,它指的是父目錄:/com/ftp/pub。如果我想進入那個目錄,我敲入命令:
% cd ..
猜一下我現在在哪兒呢?我又回到了/home/ar/alan!shell(準確的說是人工智能實驗室裡用的tcsh)認為我其實是想回到那個裝有符號鏈接的目錄。現在我必須使用"cd ./.."才能進入/com/ftp/pub。
==Shell編程==
Shell程序員和《侏羅紀公園》裡的恐龍製造者有些類似。他們手上沒有所需的完整材料,所以不得不用一些亂七八糟的材料填充。儘管有著無窮的自信和能力,他們似乎並不是總能控制住造出來的那些玩意。
理論上說,使用Shell編程比用C語言要有很多好處:Shell程序移植容易。這指的是使用shell「編程語言」寫的程序能夠在不同的體系結構和不同的Unix變種上運行,因為shell會解析這些程序,而不是把這些程序編譯成機器碼運行。而且,標準Unix Shell sh 自
從1977年以來就成為Unix中不可或缺的一部分,所以你可以在許多機器上找到它。
讓我們來驗證一下這個理論,寫個腳本列舉目錄下的所有文件,並使用file命令來顯示文件的類型:
日期: Fri, 24 Apr 92 14:45:48 EDT
發信人: Stephen Gildea
主題: Simple Shell Programming (簡單Shell編程)
收信人: UNIX-HATERS
同學們好。今天我們將學習"sh"編程。"sh" 是個簡單,用途廣泛的程序,讓我們先看個基本的例子:
打印一個目錄下所有文件的類型
(我聽到你們在後面說什麼了!那些已經會了的同學可以寫個腳本在遠程啟動一個X11客戶端,不要吵吵!)
我們學習sh編程的同時,當然也希望自己的程序是健壯,可移植和優雅的。我假設你們都讀過了相應的man手冊,所以下面這個實現應該很簡單:
file *
很不錯,是不是?簡單的答案給簡單的問題;符號 * 用來匹配目錄下的所有文件。嗯,不一定。以點(.)開頭的文件會被忽略,*不會匹配它們。也許這種情況很少發生,但既然要寫健壯的程序,我們將使用"ls"的一個特殊選項:
for file in `ls -A`
do
flie $file
done
多麼優雅,多麼健壯!不過,唉,一些系統上的"ls"不接受"-A"選項。沒問題,我們使用"-a"選項,然後再去掉"."和"..":
for file in `ls -a`
do
if [ $file != . -a $file != ..] then
file $file
fi
done
不是那麼優雅,但至少是健壯的和可移植的。你說什麼?"ls -a"也不是哪裡都能用的?沒問題,我們用"ls -f"好啦。它還快一點呢。我希望你們能從man手冊中看到所有這些東西。
唔,可能不是那麼健壯。Unix文件名中除了斜槓(/)以外可以使用任何字符。如果文件名中有個空格的話,這個腳本就完蛋了,這是因為shell會把它當成兩個文件名傳給"file"命令。不過這也不是太難對付。我們只要把它放到引用中就可以了:
for file in `ls -f`
do
if [ "$file" != . -a "$file" != ..]
then
file "$file"
fi
done
你們中可能已經有人看出來了,我們只是減少了問題,但還是沒有完全解決。因為換行符也能用在文件名中。
我們的腳本不是那麼簡單了,看來得重新評估一下我們用的方法了。如果我們不使用"ls"就不用費勁去處理它的輸出了。這個怎麼樣:
for file in * .*
do
if [ "$file" != . -a "$file" != ..]
then
file "$file"
fi
done
看起來不錯。能夠處理點(.)文件和有非打印字符的文件名。我們不斷把一些稀奇古怪的文件名加入到測試目錄下,這個腳本始終工作得很好。然而有個傢伙用它測一個空目錄,這時候 * 產生了"No such file"(沒有這個
文件)的輸出。不過,我們當然可以繼續處理這種情況...
....到了這一步uucp可能會嫌我的這封郵件可能,看來我只能到此為止了,請讀者去自己解決剩下的bug吧。
Stephen
還有一個更大的問題Stephen沒有想到,我們從一開始就有意隱藏著:Unix file 命令不工作。
日期: Sat, 25 Apr 92 17:33:12 EDT
發信人: Alan Bawden
主題: Simple Shell Programming (簡單Shell編程)
收信人: UNIX-HATERS
喔!別忙。再仔細看看。你真的想用'file'命令?如果誰想開心大笑一場可以馬上去找一台Unix機器,在有各種各樣文件的目錄下敲命令"file *"。
例如,我在有各種C源代碼文件的目錄下運行"file"——這是一些結果:
arith.c: c program text
binshow.c: c program text
bintxt.c: c program text
看起來還不錯。不過這個就不太對了:
crc.c: ascii text
看到了麼?'file'並不是根據後綴".c"去判斷的,它對文件的內容採用了一些啟髮式(heuristics)算法。很明顯crc.c看起來不那麼象C代碼——儘管對我來說它就是。
gencrc.c.~4~: ascii text
gencrc.c: c program text
估計我在第4版本以後做了一些修改,使得gencrc.c更像是C代碼了...
tcfs.h.~1~: c program text
tcfs.h: ascii text
很明顯第1版本以後的tcfs.h不太像是C代碼了。
time.h: English text
沒錯,time.h看起來更像英語,而不是一般的ascii碼。我不知道'file'是不是還能判斷出西班牙語或法語。(順便說一下,你的TeX文檔會被當成"ascii text"而不是"English text",不過這有點兒跑題了)
words.h.~1~: ascii text
words.h: English text
這可能是因為我在第1版本以後在words.h中加入了一些註釋。
我把最精采的留在最後:
arc.h: shell commands
Makefile: [nt]roff, tbl, or eqn input text
都錯得一塌糊塗。我不知道如果根據'file'的判斷結果去使用這些文件會造成什麼結果。
—Alan
沒有留言:
發佈留言