[授權發表]Shell程式設計範例之檔案操作
前言
這一週我們來探討檔案操作。
在日常學習和工作中,我們總是在不斷地和各種檔案打交道,這些檔案包括普通的文字檔案,可以執行的程式檔案,帶有控制字元的文件、存放各種檔案的目錄檔案、網路套接字檔案、裝置檔案等。這些檔案又具有諸如屬主、大小、建立和修改日期等各種屬性。檔案對應檔案系統的一些資料塊,對應磁碟等儲存裝置的一片連續空間,對應於顯示裝置卻是一些具有不同形狀的字符集。
在這一節,為了把關注點定位在檔案本身,我們不會深入探討檔案系統以及儲存裝置是如何組織檔案的(在後續章節再深入探討),而是探討我們對它最熟悉的一面,即把檔案當成是一序列的字元(一個byte)集合看待。因此之前介紹的《shell程式設計範例之字串操作》
下面我們先來介紹檔案的各種屬性,然後介紹普通檔案的一般操作。
檔案的各種屬性
首先,我們通過檔案的結構體來看看檔案到底有哪些屬性:
struct stat { dev_t st_dev; /* 裝置 */ ino_t st_ino; /* 節點 */ mode_t st_mode; /* 模式 */ nlink_t st_nlink; /* 硬連線 */ uid_t st_uid; /* 使用者ID */ gid_t st_gid; /* 組ID */ dev_t st_rdev; /* 裝置型別 */ off_t st_off; /* 檔案位元組數 */ unsigned long st_blksize; /* 塊大小 */ unsigned long st_blocks; /* 塊數 */ time_t st_atime; /* 最後一次訪問時間 */ time_t st_mtime; /* 最後一次修改時間 */ time_t st_ctime; /* 最後一次改變時間(指屬性) */ };
下面逐次來了解這些屬性,如果需要檢視某個檔案的屬性,用stat命令就可以,會按照上面的結構體把資訊列出來。另外,ls命令在跟上一定的引數後也可以顯示檔案的相關屬性,比如-l引數。
檔案型別
檔案型別對應於上面的st_mode, 檔案型別有很多,比如常規檔案、符號連結(硬連結、軟連結)、管道檔案、裝置檔案(符號裝置、塊裝置)、socket檔案等,不同的檔案型別對應不同的功能和作用。
範例:在命令列簡單地區分各類檔案
$ ls -l total 12 drwxr-xr-x 2 root root 4096 2007-12-07 20:08 directory_file prw-r--r-- 1 root root 0 2007-12-07 20:18 fifo_pipe brw-r--r-- 1 root root 3, 1 2007-12-07 21:44 hda1_block_dev_file crw-r--r-- 1 root root 1, 3 2007-12-07 21:43 null_char_dev_file -rw-r--r-- 2 root root 506 2007-12-07 21:55 regular_file -rw-r--r-- 2 root root 506 2007-12-07 21:55 regular_file_hard_link lrwxrwxrwx 1 root root 12 2007-12-07 20:15 regular_file_soft_link -> regular_file $ stat directory_file/ File: `directory_file/' Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 301h/769d Inode: 521521 Links: 2 Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2007-12-07 20:08:18.000000000 +0800 Modify: 2007-12-07 20:08:18.000000000 +0800 Change: 2007-12-07 20:08:18.000000000 +0800 $ stat null_char_dev_file File: `null_char_dev_file' Size: 0 Blocks: 0 IO Block: 4096 character special file Device: 301h/769d Inode: 521240 Links: 1 Device type: 1,3 Access: (0644/crw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2007-12-07 21:43:38.000000000 +0800 Modify: 2007-12-07 21:43:38.000000000 +0800 Change: 2007-12-07 21:43:38.000000000 +0800
說明: 在ls命令結果每行的第一個字元我們可以看到,它們之間都不相同,這正好反應了不同檔案的型別。d表示目錄,-表示普通檔案(或者硬連結),l表示符號連結,p表示管道檔案,b和c分別表示塊裝置和字元裝置(另外s表示socket檔案)。在stat命令的結果中,我們可以在第二行的最後找到說明,從上面的操作可以看出,directory_file是目錄,stat命令的結果中用directory表示,而null_char_dev_file它則用character special file說明。
範例:簡單比較它們的異同
通常,我們只會用到目錄、普通檔案、以及符號連結,很少碰到其他型別的檔案,不過這些檔案還是各有用處的,如果要做嵌入式開發或者程序通訊等,你可能會涉及到裝置檔案、有名管道(FIFO)。下面我們通過簡單的操作來反應它們之間的區別(具體的原理可能會在下一節《shell程式設計範例之檔案系統》介紹,如果感興趣,也可以提前到網上找找裝置檔案的作用、快裝置和字元裝置的區別、以及驅動程式中如何編寫相關裝置驅動等)。
對於普通檔案:就是一序列字元的集合,所以可以讀、寫等
$ echo "hello, world" > regular_file $ cat regular_file hello, world
目錄檔案下,我們可以建立新的檔案,所以目錄檔案還有叫法:資料夾,到後面我們會分析目錄檔案的結構體,它實際上存放了它下面的各個檔案的檔名。
$ cd directory_file $ touch file1 file2 file3
對於有名管道,操作起來比較有意思:如果你要讀它,除非有內容,否則阻塞;如果你要寫它,除非有人來讀,否則阻塞。它常用於程序通訊中。你可以開啟兩個終端terminal1和terminal2,試試看:
terminal1$ cat fifo_pipe #剛開始阻塞在這裡,直到下面的寫動作發生,才打印test字串 terminal2$ echo "test" > fifo_pipe
關於塊裝置,字元裝置,上面的兩個裝置檔案對應於/dev/hda1和/dev/null,如果你用過u盤,或者是寫過簡單的指令碼的話,這樣的用法你應該用過 :-)
$ mount hda1_block_dev_file /mnt #掛載硬碟的第一個分割槽到/mnt下(關於掛載的原理,我們在下一節討論) $ echo "fewfewfef" > /dev/null #/dev/null像個黑洞,什麼東西丟進去都消失殆盡
最後兩個檔案分別是regular_file檔案的硬連結和軟連結,你去讀寫它們,他們的內容是相同的,不過你去刪除它們,他們去互不相干,硬連結和軟連結又有什麼不同呢?前者可以說就是原檔案,後者呢只是有那麼一個inode,但沒有實際的儲存空間,建議用stat命令檢視它們之間的區別,包括它們的Blocks,inode等值,也可以考慮用diff比較它們的大小。
$ ls regular_file* ls regular_file* -l -rw-r--r-- 2 root root 204800 2007-12-07 22:30 regular_file -rw-r--r-- 2 root root 204800 2007-12-07 22:30 regular_file_hard_link lrwxrwxrwx 1 root root 12 2007-12-07 20:15 regular_file_soft_link -> regular_file $ rm regular_file # 刪除原檔案 $ cat regular_file_hard_link # 硬連結還在,而且裡頭的內容還有呢 fefe $ cat regular_file_soft_link cat: regular_file_soft_link: No such file or directory
雖然軟連結檔案本身還在,不過因為它本身不儲存內容,所以讀不到東西拉,這就是軟連結和硬連結的區別,該知道則麼用它們了吧。
另外,需要注意的是,硬連結不可以跨檔案系統,而軟連結則可以。另外,也不不允許給目錄建立硬連結。
範例:普通檔案再分類
檔案型別從Linux檔案系統那麼一個級別分了以上那麼多型別,不過普通檔案還是可以再分的(根據檔案內容的”資料結構“分),比如常見的文字檔案,可執行的ELF檔案,odt文件,jpg圖片格式,swap分割槽檔案,pdf檔案。除了文字檔案外,它們大多是二進位制檔案,有特定的結構,因此需要有專門的工具來建立和編輯它們。關於各類檔案的格式,可以參考相關文件標準。不過如果能夠了解Linux下可執行的ELF檔案的工作原理,可能對你非常有用。所以,如果有興趣,建議閱讀一下參考資料中和ELF檔案相關部分。
雖然各類普通檔案都有專屬的操作工具,但是我們還是可以直接讀、寫它們,這裡先提到這麼幾個工具,回頭討論細節。
od:以八進位制或者其他格式“匯出”檔案內容。 strings:讀出檔案中的字元(可列印的字元) gcc,gdb,readelf,objdump等:ELF檔案分析、處理工具(gcc編譯器、gdb偵錯程式、readelf分析elf檔案,objdump反編譯工具)
這裡補充一個非常重要的命令,file,這個命令用來檢視各類檔案的屬性。和stat命令相比,它可以進一步識別普通檔案,即stat命令顯示的regular file。因為regular file可以有各種不同的結構,因此在作業系統的支援下得到不同的解釋,執行不同的動作。雖然,Linux下,檔案也會加上特定的字尾以便使用者能夠方便地識別檔案的型別,但是Linux作業系統根據檔案頭識別各類檔案,而不是檔案字尾,這樣,在解釋相應的檔案時就更不容易出錯。下面我們簡單介紹file命令的用法。
$ file ./ ./: directory $ file /etc/profile /etc/profile: ASCII English text $ file /lib/libc-2.5.so /lib/libc-2.5.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped $ file /bin/test /bin/test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), stripped $ file /dev/hda /dev/hda: block special (3/0) $ file /dev/console /dev/console: character special (5/1) $ cp /etc/profile . $ tar zcf profile.tar.gz profile $ file profile.tar.gz profile.tar.gz: gzip compressed data, from Unix, last modified: Tue Jan 4 18:53:53 2000 $ mkfifo fifo_test $ file fifo_test fifo_test: fifo (named pipe)
更多用法見file命令的手冊,關於file命令的實現原理,請參考magic的手冊(看看/etc/file/magic檔案,瞭解什麼是檔案的magic number等)。
檔案屬主
Linux作為一個多使用者系統,為多使用者使用同一個系統提供了極大的方便,比如對於系統上的檔案,它通過屬主來區分不同的使用者,以便分配它們對不同檔案的操作許可權。為了更方便地管理,檔案屬主包括該檔案所屬使用者,以及該檔案所屬的使用者組,因為使用者可以屬於多個組。我們先來簡單介紹Linux下使用者和組的管理。
Linux下提供了一組命令用於管理使用者和組,比如使用者建立它們的useradd和groupadd,使用者刪除它們的userdel和groupdel,另外,passwd命令用於修改使用者密碼。當然,Linux還提供了兩個相應的配置,即/etc/passwd和/etc/group,另外,有些系統還把密碼單獨放到了配置檔案/etc/shadow中。關於它們的詳細用法請參考後面的資料,在這裡我們不介紹了,僅介紹檔案和使用者之間的一些關係。
範例:修改檔案的屬主
$ chown 使用者名稱:組名 檔名
如果要遞迴地修改某個目錄下所有檔案的屬主,可以新增-R選項。
在本節開頭我們列的檔案結構體中,可以看到僅僅有使用者ID和組ID的資訊,但ls -l的結果卻顯示了使用者名稱和組名資訊,這個是怎麼實現的呢?下面先看看-n的結果:
範例:檢視檔案的屬主
$ ls -n regular_file -rw-r--r-- 1 0 0 115 2007-12-07 23:45 regular_file $ ls -l regular_file -rw-r--r-- 1 root root 115 2007-12-07 23:45 regular_file
範例:分析檔案屬主實現的背後原理
可以看到,ls -n顯示了使用者ID和組ID,而ls -l顯示了它們的名字。還記得上面提到的兩個配置檔案/etc/passwd和/etc/group檔案麼?它們分別存放了使用者ID和使用者名稱,組ID和組名的對應關係,因此很容易想到ls -l命令在實現時是如何通過檔案結構體的ID資訊找到它們對應的名字資訊的。如果想對ls -l命令的實現有更進一步的瞭解,可以用strace跟蹤看看它是否讀取了/etc/passwd和/etc/group這個兩個檔案。
$ strace -f -o strace.log ls -l regular_file $ cat strace.log | egrep "passwd|group|shadow" 2989 open("/etc/passwd", O_RDONLY) = 3 2989 open("/etc/group", O_RDONLY) = 3
說明:strace是一個非常有用的工具,可以用來跟蹤系統呼叫和訊號。如同gdb等其他強大的工具一樣,它基於系統的ptrace系統呼叫實現,所以如果你感興趣,可以好好研究一下這個工具。
實際上,把屬主和許可權分開介紹不太好,因為只有它們兩者結合才使得多使用者系統成為可能,否則無法隔離不同使用者對某個檔案的操作,所以下面來介紹檔案操作許可權。
檔案許可權
從ls -l命令的結果的第一列的後9個字元中,我們可以看到類似這樣的資訊rwxr-xr-x,它們對應於檔案結構體的st_mode部分(st_mode包含檔案型別資訊和檔案許可權資訊兩部分)。這類資訊可以分成三部分,即rwx,r-x,r-x,分別對應該檔案所屬使用者,所屬組,其他組對該檔案的操作許可權,如果有rwx中任何一個表示可讀、可寫、可執行,如果為-表示沒有這個許可權。對應的,可以用八進位制來表示它,比如rwxr-xr-x就可表示成二進位制111101101,對應的八進位制則為755。正是因為這樣,我們要修改檔案的操作許可權時,也可以有多種方式來實現,它們都可通過chmod命令來修改。
範例:給檔案新增讀、寫、可執行許可權
比如,把regular_file的檔案許可權修改為所有使用者都可讀、可寫、可執行,即rwxrwxrwx,也可表示為111111111,翻譯成八進位制,則為777。這樣就可以通過兩種方式修改這個許可權。
$ chmod a+rwx regular_file
或
$ chmod 777 regular_file
說明:a指所用使用者,如果只想給使用者本身可讀可寫可執行許可權,那麼可以把a換成u;而+就是新增許可權,相反的,如果想去掉某個許可權,用-,而rwx則對應可讀、可寫、可執行。更多用法見chmod命令的幫助。
實際上除了這些許可權外,還有兩個涉及到安全方面的許可權,即setuid/setgid和只讀控制等。
如果設定了檔案(程式或者命令)的setuid/setgid許可權,那麼使用者將可用root身份去執行該檔案,因此,這將可能帶來安全隱患;如果設定了檔案的只讀許可權,那麼使用者將僅僅對該檔案將有可讀許可權,這為避免諸如rm -rf的“可惡”操作帶來一定的庇佑。
範例:授權普通使用者執行root所屬命令
預設情況下,系統是不允許普通使用者執行passwd命令的,通過setuid/setgid,可以授權普通使用者執行它。
$ ls -l /usr/bin/passwd -rwx--x--x 1 root root 36092 2007-06-19 14:59 /usr/bin/passwd $ su #切換到root使用者,給程式或者命令新增“粘著位” $ chmod +s /usr/bin/passwd $ ls -l /usr/bin/passwd -rws--s--x 1 root root 36092 2007-06-19 14:59 /usr/bin/passwd $ exit $ passwd #普通使用者通過執行該命令,修改自己的密碼
說明:
setuid 和setgid位是讓普通使用者可以以root使用者的角色執行只有root帳號才能執行的程式或命令。
雖然這在一定程度上為管理提供了方便,比如上面的操作讓普通使用者可以修改自己的帳號,而不是要root帳號去為每個使用者做這些工作。關於setuid/setgid的更多詳細解釋,請參考最後推薦的資料。
範例:給重要檔案加鎖
只讀許可權示例:給重要檔案加鎖(新增不可修改位[immutable])),以避免各種誤操作帶來的災難性後果(例如: rm -rf)
$ chattr +i regular_file $ lsattr regular_file ----i-------- regular_file $ rm regular_file #加了immutable位以後,你無法對檔案進行任何“破壞性”的活動啦 rm: remove write-protected regular file `regular_file'? y rm: cannot remove `regular_file': Operation not permitted $ chattr -i regular_file #如果想對它進行常規操作,那麼可以把這個位去掉 $ rm regular_file
說明:chattr可以用設定檔案的特殊許可權,更多用法請參考chattr的幫助。
檔案大小
普通檔案是檔案內容的大小,而目錄作為一個特殊的檔案,它存放的內容是以目錄結構體組織的各類檔案資訊,所以目錄的大小一般都是固定的,它存放的檔案個數自然也就有上限,即少於它的大小除以檔名的長度。裝置檔案的檔案大小則對應裝置的主、次裝置號,而有名管道檔案因為特殊的讀寫性質,所以大小常是0。硬連結(目錄檔案不能建立硬連結)實質上是原檔案的一個完整的拷比,因此,它的大小就是原檔案的大小。而軟連結只是一個inode,存放了一個指向原檔案的指標,因此它的大小僅僅是原檔名的位元組數。下面我們通過演示增加記憶。
範例:檢視普通檔案和連結檔案
原檔案,連結檔案檔案大小的示例:
$ echo -n "abcde" > regular_file #往regular_file寫入5位元組 $ ls -l regular_file* -rw-r--r-- 2 root root 5 2007-12-08 15:28 regular_file -rw-r--r-- 2 root root 5 2007-12-08 15:28 regular_file_hard_file lrwxrwxrwx 1 root root 12 2007-12-07 20:15 regular_file_soft_link -> regular_file lrwxrwxrwx 1 root root 22 2007-12-08 15:21 regular_file_soft_link_link -> regular_file_soft_link $ i="regular_file" $ j="regular_file_soft_link" $ echo ${#i} ${#j} #可以參考,軟連結存放的剛好是它們指向的原檔案的檔名的位元組數 12 22
範例:檢視裝置檔案
裝置號對應的檔案大小:主、次裝置號
$ ls -l hda1_block_dev_file brw-r--r-- 1 root root 3, 1 2007-12-07 21:44 hda1_block_dev_file $ ls -l null_char_dev_file crw-r--r-- 1 root root 1, 3 2007-12-07 21:43 null_char_dev_file
補充:主(major)、次(minor)裝置號的作用有不同。當一個裝置檔案被開啟時,核心會根據主裝置號(major number)去查詢在核心中已經以主裝置號註冊的驅動(可以cat /proc/devices檢視已經註冊的驅動號和主裝置號的對應情況),而次裝置號(minor number)則是通過核心傳遞給了驅動本身(參考《The Linux Primer》第十章)。因此,對於核心而言,通過主裝置號就可以找到對應的驅動去識別某個裝置,而對於驅動而言,為了能夠更復雜地訪問裝置,比如訪問裝置的不同部分(如硬體通過分割槽分成不同部分,而出現hda1,hda2,hda3等),比如產生不同要求的隨機數(如/dev/random和/dev/urandom等)。
範例:檢視目錄
目錄檔案的大小,為什麼是這樣呢?看看下面的目錄結構體的大小,目錄檔案的Block中存放的該目錄下所有檔名的入口。
$ ls -ld directory_file/ drwxr-xr-x 2 root root 4096 2007-12-07 23:14 directory_file/
目錄的結構體如下:
struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[NAME_MAX+1]; /* 檔名稱 */ }
檔案訪問、更新、修改時間
檔案的時間屬性可以記錄使用者對檔案的操作資訊,在系統管理、判斷檔案版本資訊等情況下將為管理員提供參考。因此,在閱讀檔案時,建議用cat等閱讀工具,不要用編輯工具vim去閱讀,因為即使你沒有做任何修改操作,一旦你執行了儲存命令,你將修改檔案的時間戳資訊。
檔名
檔名並沒有存放在檔案結構體裡,而是存放在它所在的目錄結構體中。所以,在目錄的同一級別中,檔名必須是唯一的。
檔案的基本操作
對於檔案,常見的操作包括建立、刪除、修改、讀、寫等。關於各種操作對應的“背後動作”我們將在下一章《shell程式設計範例之檔案系統操作》詳細分析。
範例:建立檔案
socket檔案是一類特殊的檔案,可以通過C語言建立,這裡不做介紹(暫時不知道是否可以用命令直接建立),其他檔案我們將通過命令建立。
$ touch regular_file #建立普通檔案 $ mkdir directory_file #建立目錄檔案,目錄檔案裡頭可以包含更多檔案 $ ln regular_file regular_file_hard_link #硬連結,是原檔案的一個完整拷比 $ ln -s regular_file regular_file_soft_link #類似一個檔案指標,指向原檔案 $ mkfifo fifo_pipe #或者通過 "mknod fifo_pipe p" 來建立,FIFO滿足先進先出的特點 $ mknod hda1_block_dev_file b 3 1 #塊裝置 $ mknod null_char_dev_file c 1 3 #字元裝置
建立一個檔案實際上是在檔案系統中添加了一個節點(inode),該節點資訊將儲存到檔案系統的節點表中。更形象地說,就是在一顆樹上長了一顆新的葉子(檔案)或者枝條(目錄檔案,上面還可以長葉子的那種),這些可以通過tree命令或者ls命令形象地呈現出來。檔案系統從日常使用的角度,完全可以當成一顆倒立的樹來看,因為它們太像了,太容易記憶啦。
$ tree 當前目錄
或者
$ ls 當前目錄
範例:刪除檔案
刪除檔案最直接的印象是這個檔案再也不存在啦,這同樣可以通過ls或者tree命令呈現出來,就像樹木被砍掉一個分支或者摘掉一片葉子一樣。實際上,這些檔案刪除之後,並不是立即消失了,而是僅僅做了刪除標記,因此,如果刪除之後,沒有相關的磁碟寫操作把相應的磁碟空間“覆蓋”,那麼原理上是可以恢復的(雖然如此,但是這樣的工作往往是很麻煩的,所以在刪除一些重要資料時,請務必三思而後行,比如做好備份工作),相應的做法可以參考資料[18]到[21]。
具體刪除檔案的命令有rm,如果要刪除空目錄,可以用rmdir命令。例如:
$ rm regular_file $ rmdir directory_file $ rm -r directory_file_not_empty
rm有兩個非常重要的引數,一個是-f,這個命令是非常“野蠻的”(關於rm -rf的那些鍾愛者輕強烈建議您閱讀的相應章節),它估計給很多linux user帶來了痛苦,另外一個是-i,這個命令是非常“溫柔的”,它估計讓很多使用者感覺煩躁不已過。用哪個還是根據您的“心情”吧,如果做好了充分的備份工作,或者採取了一些有效避免災難性後果的動作的話,您在做這些工作的時候就可以放心一些啦。
範例:複製檔案
檔案的複製通常是指檔案內容的“臨時”複製。通過這一節開頭的介紹,我們應該瞭解到,檔案的硬連結和軟連結在某種意義上說也是“檔案的複製”,前者同步複製檔案內容,後者在讀寫的情況下同步“複製”檔案內容。例如:
用cp命令常規地複製檔案(複製目錄需要-r選項)
$ cp regular_file regular_file_copy $ cp -r diretory_file directory_file_copy
建立硬連結(link和copy不同之處是後者是同步更新,前者則不然,複製之後兩者不再相關)
$ ln regular_file regular_file_hard_link
建立軟連結
$ ln -s regular_file regluar_file_soft_link
範例:修改檔名
修改檔名實際上僅僅修改了檔名識別符號。我們可以通過mv命令來實現修改檔名操作(即重新命名)。
$ mv regular_file regular_file_new_name
範例:編輯檔案
編輯檔案實際上是操作檔案的內容,對應普通文字檔案的編輯,這裡主要涉及到檔案內容的讀、寫、追加、刪除等。這些工作通常會通過專門的編輯器來做,這類編輯器有命令列下的vim、emacs和圖形介面下的gedit,kedit等。如果是一些特定的檔案,會有專門的編輯和處理工具,比如影象處理軟體gimp,文件編輯軟體OpenOffice等。這些工具一般都會有專門的教程。關於vim的用法,建議閱讀這篇帖子:VIM高階命令集錦
下面主要簡單介紹Linux下通過重定向來實現檔案的這些常規的編輯操作。
建立一個檔案並寫入abcde
$ echo "abcde" > new_regular_file
再往上面的檔案中追加一行abcde
$ echo "abcde" >> new_regular_file
按行讀一個檔案
$ while read LINE; do echo $LINE; done
$ cat toupper.sh
#!/bin/bash
# the {} will be expended to the current line and becomen the first argument of this script
FROM=$1
BASENAME=${FROM##*/}
BASE=${BASENAME%.*}
SUFFIX=${BASENAME##*.}
TOSUFFIX="$(echo $SUFFIX | tr '[a-z]' '[A-Z]')"
TO=$2/$BASE.$TOSUFFIX
COM="mv $FROM $TO"
echo $COM
eval $COM
updatedb+locate基本使用演示
$ updatedb #更新庫 $ locate find*.gz #查詢包含find字串的所有gz壓縮包
實際上,除了上面兩種命令外,Linux下還有命令查詢工具:which和whereis,前者用於返回某個命令的全路徑,而後者用於返回某個命令、原始檔、man檔案的路徑。例如,我們需要查詢find命令的絕對路徑:
$ which find /usr/bin/find $ whereis find find: /usr/bin/find /usr/X11R6/bin/find /usr/bin/X11/find /usr/X11/bin/find /usr/man/man1/find.1.gz /usr/share/man/man1/find.1.gz /usr/X11/man/man1/find.1.gz
需要提到的是,如果想根據檔案的內容搜尋檔案,那麼find和updatedb+locate以及which,whereis都無能為例啦,可選的方法是 grep,sed等命令,前者在加上-r引數以後可以在指定目錄下檔案中搜索指定的檔案內容,後者再使用-i引數後,可以對檔案內容進行替換。它們的基本 用法在前面的章節中我們已經詳細介紹了,所以這裡就不敘述。
值得強調的是,這些命令對檔案的操作是非常有意義的。它們在某個程度上把檔案 系統結構給抽象了,使得對整個檔案系統的操作簡化為對單個檔案的操作,而單個檔案如果僅僅考慮文字部分,那麼最終卻轉化成了我們之前的字串操作,即我們 上一節討論過的內容。為了更清楚的瞭解檔案的組織結構,檔案之間的關係,在下一節我們將深入探討檔案系統。
參考資料
後記
- 考慮到檔案和檔案系統的重要性,我們將把它分成三個小節來介紹:檔案、檔案系統、程式與程序。在檔案這一部分,我們主要介紹檔案的基本屬性和常規操作,在 檔案系統那部分,將深入探討Linux 檔案系統的各個部分(包括Linux 檔案系統的結構、具體某個檔案系統的大體結構分析、底層驅動的工作原理),在程式與程序一節將專門討論可執行檔案的相關內容(包括不同的程式型別、載入執 行過程、不同程序之間的互動[命令管道和無名管道、訊號通訊]、對程序的控制等)。
- 有必要討論清楚 目錄大小 的含義,另外,最好把一些常規的檔案操作全部考慮到,包括檔案的讀、寫、執行、刪除、修改、複製、壓縮/解壓縮等。
- 下午剛從上海回來,比賽結果很“糟糕”,不過到現在已經不重要了,關鍵是通過決賽發現了很多不足,發現了設計在系統開發中的關鍵角色,並且發現了上海是個美麗的城市,上交也是個美麗的大學。回來就開始整理這個因為比賽落下了兩週的blog。
- 12月15日,新增檔案搜尋部分內容。