歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> 討厭的ls不能隨意顯示子目錄

討厭的ls不能隨意顯示子目錄

日期:2017/2/27 14:18:53   编辑:更多Linux
  ls 是最為熟知的 Unix 命令之一(猶如 DOS 裡的 dir ),大家都已經習慣了它的許多用法。乍聽“討厭”二字,你可能接受不了。然而,錘煉了這麼久的 ls 程序,也許從一開始就存在著明顯的毛病。當你不帶參數使用 ls 時,它能如你所願,列出當前目錄下的所有文件和目錄名(點文件除外)。這時如果你發現列出的東西太多,想縮小一下范圍,自然就想到使用 ls a* 之類的命令。遺憾的是,這條命令列出的東西常常(不是少了,而是)更多!(多到令人氣憤的程度!)因為它不僅列出了以 a 打頭的文件名,而且也列出了以 a 打頭的目錄中的(全部!)文件,這是你一點也不感興趣的,因為你極少要求將當前目錄中的部分文件和某些一級子目錄中的所有文件一並列出,這樣的組合是很古怪的。你頂多對 -R 選項感興趣,它是請求列出整個目錄樹(包括所有子目錄中的文件)。作為文件列表的專用命令,如果像 ls 這樣不能“善解人意”的話,那麼說它“討厭”也不算太過分吧!    也許有的朋友會說,-d 參數可以抑制子目錄內容的輸出,即用 ls -d a* 可以達到目的。然而問題是,對於如此頻繁使用的命令來說,時常敲入 -d 是一件煩瑣的事,絕對不能令人接受。多數情況是,先使用了 ls a*;待發現苗頭不對時,才准備使用 ls -d a* ;而這時屏幕上早已混亂不堪,不可能再用鼠標去快捷地選用先前屏幕上你想要的文本了。 有朋友說,可以利用 shell 的別名機制,將 ls 重定義為 ls -d ;然而在目前,這又會帶來其它的問題。    首先,ls -d 會將所有的目錄內容都隱去,例如:ls -d mydir 將只產生一個結果,就是 mydir 本身而不是目錄的內容,而你想要的恰恰是 mydir 包含的文件。這時你大概沒有辦法了,因為你已經將 ls 重定義為 ls -d 了,並且不存在專門撤銷 -d 選項的其它選項。雖然你可以用 “ls” 來暫時繞過別名,但如此拐彎抹角,不是同樣令人難受嗎?    其次,要想簡單地列出 mydir 所包含的全部目錄項(包括點文件)幾乎是不可能的。僅僅用 ls -ad mydir/* 是不行的,因為由 shell 解釋的 * 號是不包括點文件的(暫不討論 shell 的 dotglob 選項,事實上人們極少使用這一選項)。有的人使用許許多多的別名,代表不同的參數選項,如 ll, la, ld 等等,但是多記憶一條命令也是一個負擔,而且不標准,不通用,還可能與別的命令名相沖突。可見在舊的 ls 框架下,重定義不能帶來預期的好處。    總之,ls 使我們受到很大的約束,是極不理想的。多年來,大家各自都有權宜之計,但都不想從根本上改變它。看來這一“重”任落到了我們這些無名小卒身上。是的,我們是非改不可的;因為我們要營造完美的系統,它是我們的珍愛,它是我們的家!!    如果你深有同感,而且喜歡大膽嘗試,那麼新的 ls 已為你做好,現在你就能如願以償了!    首先請下載: http://metalab.unc.edu/pub/gnu/fileutils/fileutils-4.0.tar.gz (壓縮大小 1.1 MBytes) 然後下載 ls 的補丁( 2000-01-01 創建,壓縮大小 2707 字節)。該補丁實際上是 fileutils 的補丁。用 tar, gzip, gunzip, patch, make 等命令進行解包、修補和編譯,生成新的 ls 執行程序。修補後的 ls 同舊的 ls 保持了極大的兼容性(但不是100%的兼容)。當不用 -d 選項時,兩者完全等價;當使用 -d 選項時,兩者也只有細微的差別。由於 ls 是一個系統命令,兼容性是至關重要的,希望這點差別不至於使系統的運行有任何失常。請朋友們將舊的 ls 留一個備份(重要喲!),萬一系統出了毛病,只需要簡單地恢復舊有的 ls 即可。下面詳細說明帶 -d 選項的新舊 ls 的差別。    1.不帶文件名參數的舊的 ls -d 列出當前目錄項本身,而不是當前目錄中的全部文件;不帶文件名參數的新的 ls -d 列出當前目錄中的全部文件,而不是當前目錄項本身。    說明:無論是否有 -d 選項,不帶文件名參數的新的 ls 都列出當前目錄中的全部文件,而不是當前目錄項本身;因為這正是我們最頻繁遇到的情況。相反,僅僅請求“列出當前目錄項本身”,這是個不常用的操作,可以用帶有點參數的 “ls -d .” 來實現。    2.帶有文件名參數的舊的 ls -d 總是列出目錄項本身,而不是目錄的內容。    3.帶有文件名參數的新的 ls -d 能夠區分命令行中的目錄名是否以 “/”結尾。這個 “/” 號表示請求列出子目錄的內容,不列出該目錄項本身。否則,如果不以 “/”結尾,那麼總是列出目錄項本身,而不是子目錄的內容。輸出的方式完全由目錄名結尾是否有“/”號來決定。    說明:根據這條規則,“ls -d /” 將列出根目錄的內容,而“ls -d /.”只列出根目錄項本身。在命令行中,以 “/” 結尾的和不以“/”結尾的諸多目錄名可以任意混用。對於那些不以“/”結尾的目錄名參數來說,新舊 ls -d 的輸出結果沒有任何差別。所以,新舊 ls 的整體差別很小。 4. 新的 ls -d -R mydir 或 ls -d -R mydir/ 中的 -R 選項使得 -d 選項不起作用,遞歸地列出 mydir 及其任一級子目錄中的全部文件。舊的 ls -d -R mydir 或 ls -d -R mydir/ 中的 -d 選項優先,僅僅列出 mydir 這個目錄項。


   說明:假定我們已經將 ls 重定義為“ls -d ” ,那麼新的 ls 程序使我們可以用 ls -R mydir 來列出整棵目錄樹的內容,而不必擔心其中 -d 的抑制作用。    建議:在個人初始化文件中用別名機制重定義 ls 為 ls -d,以便利用新的 ls 所帶來的好處。現在,你可以自由地在目錄名尾部加上“/” 或“/.”或什麼也不加,來控制 ls 以你所要的方式進行輸出。本文開頭提到的不倫不類的文件列表組合,現在不再出現了。現在的“ls a*”(注意其中的 ls 內含 -d 選項,否則將與舊 ls 的效果相同)只列出當前目錄下以 a 打頭的項目,不再混雜著子目錄中的文件。另外,你已經看到,在新的 ls 框架下,代表“當前目錄”的特殊目錄名“.”可以發揮重要的作用。



Copyright © Linux教程網 All Rights Reserved