鸟哥的Linux私房菜(基础篇)- 第七章、Linux 文件与目录管理
最近升級日期:2009/08/26
| 在第六章我們認識了Linux系統下的文件權限概念以及目錄的配置說明。在這個章節當中,我們就直接來進一步的操作與管理文件與目錄吧!包括在不同的目錄間變換、創建與刪除目錄、創建與刪除文件,還有尋找文件、查閱文件內容等等,都會在這個章節作個簡單的介紹啊! |
1. 目錄與路徑
1.1 相對路徑與絕對路徑
1.2 目錄的相關操作: cd, pwd, mkdir, rmdir
1.3 關於運行檔路徑的變量: $PATH
2. 文件與目錄管理
2.1 文件與目錄的檢視: ls
2.2 復制、刪除與移動: cp, rm, mv
2.3 取得路徑的文件名稱與目錄名稱
3. 文件內容查閱:
3.1 直接檢視文件內容: cat, tac, nl
3.2 可翻頁檢視: more, less
3.3 數據擷取: head, tail
3.4 非純文字檔: od
3.5 修改文件時間與建置新檔: touch
4. 文件與目錄的默認權限與隱藏權限
4.1 文件默認權限:umask
4.2 文件隱藏屬性: chattr, lsattr
4.4 文件特殊權限:SUID, SGID,SBIT, 權限配置
4.3 觀察文件類型:file
5. 命令與文件的搜尋:
5.1 命令檔名的搜尋:which
5.2 文件檔名的搜尋:whereis,locate, find
6. 極重要!權限與命令間的關系:
7. 重點回顧
8. 本章習題
9. 參考數據與延伸閱讀
10. 針對本文的建議:http://phorum.vbird.org/viewtopic.php?t=23879
目錄與路徑:
由第六章Linux的文件權限與目錄配置中透過FHS了解了Linux的『樹狀目錄』概念之后,接下來就得要實際的來搞定一些基本的路徑問題了!這些目錄的問題當中,最重要的莫過於第六章也談過的『絕對路徑』與『相對路徑』的意義啦!絕對/相對路徑的寫法并不相同,要特別注意。此外,當你下達命令時,該命令是透過什么功能來取得的?這與PATH這個變量有關呢!底下就讓我們來談談羅!
相對路徑與絕對路徑:
在開始目錄的切換之前,你必須要先了解一下所謂的『路徑(PATH)』,有趣的是:什么是『相對路徑』與『絕對路徑』?雖然前一章已經稍微針對這個議題提過一次,不過,這里不厭其煩的再次的強調一下!
- 絕對路徑:路徑的寫法『一定由根目錄/ 寫起』,例如: /usr/share/doc 這個目錄。
- 相對路徑:路徑的寫法『不是由/ 寫起』,例如由 /usr/share/doc 要到 /usr/share/man 底下時,可以寫成:『cd ../man』這就是相對路徑的寫法啦!相對路徑意指『相對於目前工作目錄的路徑!』
- 相對路徑的用途
那么相對路徑與絕對路徑有什么了不起呀?喝!那可真的是了不起了!假設你寫了一個軟件,這個軟件共需要三個目錄,分別是 etc, bin, man 這三個目錄,然而由於不同的人喜歡安裝在不同的目錄之下,假設甲安裝的目錄是 /usr/local/packages/etc, /usr/local/packages/bin 及 /usr/local/packages/man ,不過乙卻喜歡安裝在 /home/packages/etc, /home/packages/bin, /home/packages/man 這三個目錄中,請問如果需要用到絕對路徑的話,那么是否很麻煩呢?是的!如此一來每個目錄下的東西就很難對應的起來!這個時候相對路徑的寫法就顯的特別的重要了!
此外,如果你跟鳥哥一樣,喜歡將路徑的名字寫的很長,好讓自己知道那個目錄是在干什么的,例如:/cluster/raid/output/taiwan2006/smoke 這個目錄,而另一個目錄在 /cluster/raid/output/taiwan2006/cctm ,那么我從第一個要到第二個目錄去的話,怎么寫比較方便?當然是『cd ../cctm 』比較方便羅!對吧!
- 絕對路徑的用途
但是對於檔名的正確性來說,『絕對路徑的正確度要比較好~』。一般來說,鳥哥會建議你,如果是在寫程序 (shell scripts) 來管理系統的條件下,務必使用絕對路徑的寫法。怎么說呢?因為絕對路徑的寫法雖然比較麻煩,但是可以肯定這個寫法絕對不會有問題。如果使用相對路徑在程序當中,則可能由於你運行的工作環境不同,導致一些問題的發生。這個問題在工作排程(at, cron, 第十六章)當中尤其重要!這個現象我們在十三章、shell script時,會再次的提醒你喔! ^_^
目錄的相關操作:
我們之前稍微提到變換目錄的命令是cd,還有哪些可以進行目錄操作的命令呢?例如創建目錄啊、刪除目錄之類的~還有,得要先知道的,就是有哪些比較特殊的目錄呢?舉例來說,底下這些就是比較特殊的目錄,得要用力的記下來才行:
| . 代表此層目錄 .. 代表上一層目錄 - 代表前一個工作目錄 ~ 代表『目前使用者身份』所在的家目錄 ~account 代表 account 這個使用者的家目錄(account是個帳號名稱) |
需要特別注意的是:在所有目錄底下都會存在的兩個目錄,分別是『.』與『..』分別代表此層與上一級目錄的意思。那么來思考一下底下這個例題:
| 例題: 請問在Linux底下,根目錄下有沒有上一級目錄(..)存在? 答: 若使用『 ls -al / 』去查詢,可以看到根目錄下確實存在 . 與 .. 兩個目錄,再仔細的查閱,可發現這兩個目錄的屬性與權限完全一致,這代表根目錄的上一層(..)與根目錄自己(.)是同一個目錄。 |
底下我們就來談一談幾個常見的處理目錄的命令吧:
- cd:變換目錄
- pwd:顯示目前的目錄
- mkdir:創建一個新的目錄
- rmdir:刪除一個空的目錄
- cd (變換目錄)
我們知道vbird這個使用者的家目錄是/home/vbird/,而root家目錄則是/root/,假設我以root身份在 Linux系統中,那么簡單的說明一下這幾個特殊的目錄的意義是:
| [root@www ~]# cd [相對路徑或絕對路徑] # 最重要的就是目錄的絕對路徑與相對路徑,還有一些特殊目錄的符號羅! [root@www ~]# cd ~vbird # 代表去到 vbird 這個使用者的家目錄,亦即 /home/vbird [root@www vbird]# cd ~ # 表示回到自己的家目錄,亦即是 /root 這個目錄 [root@www ~]# cd # 沒有加上任何路徑,也還是代表回到自己家目錄的意思喔! [root@www ~]# cd .. # 表示去到目前的上一級目錄,亦即是 /root 的上一級目錄的意思; [root@www /]# cd - # 表示回到剛剛的那個目錄,也就是 /root 羅~ [root@www ~]# cd /var/spool/mail # 這個就是絕對路徑的寫法!直接指定要去的完整路徑名稱! [root@www mail]# cd ../mqueue # 這個是相對路徑的寫法,我們由/var/spool/mail 去到/var/spool/mqueue 就這樣寫! |
cd是Change Directory的縮寫,這是用來變換工作目錄的命令。注意,目錄名稱與cd命令之間存在一個空格。一登陸Linux系統后,root會在root的家目錄!那回到上一層目錄可以用『 cd .. 』。利用相對路徑的寫法必須要確認你目前的路徑才能正確的去到想要去的目錄。例如上表當中最后一個例子,你必須要確認你是在/var/spool/mail當中,并且知道在/var/spool當中有個mqueue的目錄才行啊~這樣才能使用cd ../mqueue去到正確的目錄說,否則就要直接輸入cd /var/spool/mqueue羅~
其實,我們的提示字節,亦即那個 [root@www ~]# 當中,就已經有指出目前的目錄了,剛登陸時會到自己的家目錄,而家目錄還有一個代碼,那就是『 ~ 』符號!例如上面的例子可以發現,使用『 cd ~ 』可以回到個人的家目錄里頭去呢!另外,針對 cd 的使用方法,如果僅輸入 cd 時,代表的就是『 cd ~ 』的意思喔~亦即是會回到自己的家目錄啦!而那個『 cd - 』比較難以理解,請自行多做幾次練習,就會比較明白了。
| Tips: 還是要一再地提醒,我們的 Linux 的默認命令列模式 (bash shell) 具有文件補齊功能,你要常常利用 [tab] 按鍵來達成你的目錄完整性啊!這可是個好習慣啊~可以避免你按錯鍵盤輸入錯字說~ ^_^ |
- pwd (顯示目前所在的目錄)
| [root@www ~]# pwd [-P] 選項與參數: -P :顯示出確實的路徑,而非使用連結 (link) 路徑。范例:單純顯示出目前的工作目錄: [root@www ~]# pwd /root <== 顯示出目錄啦~范例:顯示出實際的工作目錄,而非連結檔本身的目錄名而已 [root@www ~]# cd /var/mail <==注意,/var/mail是一個連結檔 [root@www mail]# pwd /var/mail <==列出目前的工作目錄 [root@www mail]# pwd -P /var/spool/mail <==怎么回事?有沒有加 -P 差很多~ [root@www mail]# ls -ld /var/mail lrwxrwxrwx 1 root root 10 Sep 4 17:54 /var/mail -> spool/mail # 看到這里應該知道為啥了吧?因為 /var/mail 是連結檔,連結到 /var/spool/mail # 所以,加上 pwd -P 的選項后,會不以連結檔的數據顯示,而是顯示正確的完整路徑啊! |
pwd是Print Working Directory的縮寫,也就是顯示目前所在目錄的命令,例如在上個表格最后的目錄是/var/mail這個目錄,但是提示字節僅顯示mail,如果你想要知道目前所在的目錄,可以輸入pwd即可。此外,由於很多的套件所使用的目錄名稱都相同,例如 /usr/local/etc還有/etc,但是通常Linux僅列出最后面那一個目錄而已,這個時候你就可以使用pwd 來知道你的所在目錄羅!免得搞錯目錄,結果...
其實有趣的是那個 -P 的選項啦!他可以讓我們取得正確的目錄名稱,而不是以連結檔的路徑來顯示的。如果你使用的是CentOS 5.x的話,剛剛好/var/mail是/var/spool/mail的連結檔,所以,透過到/var/mail下達pwd -P就能夠知道這個選項的意義羅~ ^_^
- mkdir (創建新目錄)
| [root@www ~]# mkdir [-mp] 目錄名稱 選項與參數: -m :配置文件的權限喔!直接配置,不需要看默認權限 (umask) 的臉色~ -p :幫助你直接將所需要的目錄(包含上一級目錄)遞回創建起來!范例:請到/tmp底下嘗試創建數個新目錄看看: [root@www ~]# cd /tmp [root@www tmp]# mkdir test <==創建一名為 test 的新目錄 [root@www tmp]# mkdir test1/test2/test3/test4 mkdir: cannot create directory `test1/test2/test3/test4': No such file or directory <== 沒辦法直接創建此目錄啊! [root@www tmp]# mkdir -p test1/test2/test3/test4 # 加了這個 -p 的選項,可以自行幫你創建多層目錄!范例:創建權限為rwx--x--x的目錄 [root@www tmp]# mkdir -m 711 test2 [root@www tmp]# ls -l drwxr-xr-x 3 root root 4096 Jul 18 12:50 test drwxr-xr-x 3 root root 4096 Jul 18 12:53 test1 drwx--x--x 2 root root 4096 Jul 18 12:54 test2 # 仔細看上面的權限部分,如果沒有加上 -m 來強制配置屬性,系統會使用默認屬性。 # 那么你的默認屬性為何?這要透過底下介紹的 umask 才能了解喔! ^_^ |
如果想要創建新的目錄的話,那么就使用mkdir (make directory)吧! 不過,在默認的情況下,你所需要的目錄得一層一層的創建才行!例如:假如你要創建一個目錄為 /home/bird/testing/test1,那么首先必須要有 /home 然后 /home/bird ,再來 /home/bird/testing 都必須要存在,才可以創建 /home/bird/testing/test1 這個目錄!假如沒有 /home/bird/testing 時,就沒有辦法創建 test1 的目錄羅!
不過,現在有個更簡單有效的方法啦!那就是加上 -p 這個選項喔!你可以直接下達:『 mkdir -p /home/bird/testing/test1 』則系統會自動的幫你將 /home, /home/bird, /home/bird/testing 依序的創建起目錄!并且,如果該目錄本來就已經存在時,系統也不會顯示錯誤信息喔!挺快樂的吧! ^_^。不過鳥哥不建議常用-p這個選項,因為擔心如果你打錯字,那么目錄名稱就會變的亂七八糟的!
另外,有個地方你必須要先有概念,那就是『默認權限』的地方。我們可以利用 -m 來強制給予一個新的目錄相關的權限,例如上表當中,我們給予 -m 711 來給予新的目錄 drwx--x--x 的權限。不過,如果沒有給予 -m 選項時,那么默認的新建目錄權限又是什么呢?這個跟umask 有關,我們在本章后頭會加以介紹的。
- rmdir (刪除『空』的目錄)
| [root@www ~]# rmdir [-p] 目錄名稱 選項與參數: -p :連同上一級『空的』目錄也一起刪除范例:將於mkdir范例中創建的目錄(/tmp底下)刪除掉! [root@www tmp]# ls -l <==看看有多少目錄存在? drwxr-xr-x 3 root root 4096 Jul 18 12:50 test drwxr-xr-x 3 root root 4096 Jul 18 12:53 test1 drwx--x--x 2 root root 4096 Jul 18 12:54 test2 [root@www tmp]# rmdir test <==可直接刪除掉,沒問題 [root@www tmp]# rmdir test1 <==因為尚有內容,所以無法刪除! rmdir: `test1': Directory not empty [root@www tmp]# rmdir -p test1/test2/test3/test4 [root@www tmp]# ls -l <==您看看,底下的輸出中test與test1不見了! drwx--x--x 2 root root 4096 Jul 18 12:54 test2 # 瞧!利用 -p 這個選項,立刻就可以將 test1/test2/test3/test4 一次刪除~ # 不過要注意的是,這個 rmdir 僅能『刪除空的目錄』喔! |
如果想要刪除舊有的目錄時,就使用rmdir吧!例如將剛剛創建的test殺掉,使用『 rmdir test 』即可!請注意呦!目錄需要一層一層的刪除才行!而且被刪除的目錄里面必定不能存在其他的目錄或文件!這也是所謂的空的目錄(empty directory)的意思啊!那如果要將所有目錄下的東西都殺掉呢?!這個時候就必須使用『 rm -r test 』羅!不過,還是使用 rmdir 比較不危險!你也可以嘗試以 -p 的選項加入,來刪除上一級的目錄喔!
關於運行檔路徑的變量: $PATH
經過第六章FHS的說明后,我們知道查閱文件屬性的命令ls完整檔名為:/bin/ls(這是絕對路徑),那你會不會覺得很奇怪:『為什么我可以在任何地方運行/bin/ls這個命令呢? 』為什么我在任何目錄下輸入 ls 就一定可以顯示出一些信息而不會說找不到該 /bin/ls 命令呢?這是因為環境變量 PATH 的幫助所致呀!
當我們在運行一個命令的時候,舉例來說『ls』好了,系統會依照PATH的配置去每個PATH定義的目錄下搜尋檔名為ls的可運行檔,如果在PATH定義的目錄中含有多個檔名為ls的可運行檔,那么先搜尋到的同名命令先被運行!
現在,請下達『echo $PATH』來看看到底有哪些目錄被定義出來了?echo有『顯示、印出』的意思,而 PATH 前面加的 $ 表示后面接的是變量,所以會顯示出目前的 PATH !
| 范例:先用root的身份列出搜尋的路徑為何? [root@www ~]# echo $PATH /usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin :/bin:/usr/sbin:/usr/bin:/root/bin <==這是同一行!范例:用vbird的身份列出搜尋的路徑為何? [root@www ~]# su - vbird [vbird@www ~]# echo $PATH /usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/vbird/bin # 仔細看,一般用戶vbird的PATH中,并不包含任何『sbin』的目錄存在喔! |
PATH(一定是大寫)這個變量的內容是由一堆目錄所組成的,每個目錄中間用冒號(:)來隔開,每個目錄是有『順序』之分的。仔細看一下上面的輸出,你可以發現到無論是root還是vbird都有/bin這個目錄在PATH變量內,所以當然就能夠在任何地方運行ls來找到/bin/ls運行檔羅!
我們用幾個范例來讓你了解一下,為什么PATH是那么重要的項目!
| 例題: 請問你能不能使用一般身份使用者下達ifconfig eth0這個命令呢? 答: 如上面的范例所示,當你使用vbird這個帳號運行ifconfig時,會出現『-bash: ifconfig: command not found』的字樣,因為ifconfig的是放置到/sbin底下,而由上表的結果中我們可以發現vbird的PATH并沒有配置/sbin,所以默認無法運行。 但是你可以使用『/sbin/ifconfig eth0』來運行這個命令喔!因為一般用戶還是可以使用ifconfig來查詢系統IP的參數,既然PATH沒有規范到/sbin,那么我們使用『絕對路徑』也可以運行到該命令的! |
例題: 假設你是root,如果你將ls由/bin/ls移動成為/root/ls(可用『mv /bin/ls /root』命令達成),然后你自己本身也在/root目錄下,請問(1)你能不能直接輸入ls來運行?(2)若不能,你該如何運行ls這個命令?(3)若要直接輸入ls即可運行,又該如何進行? 答: 由於這個例題的重點是將某個運行檔移動到非正規目錄去,所以我們先要進行底下的動作才行:(務必使用root的身份)
(2)因為這個ls確實存在於/root底下,并不是被刪除了!所以我們可以透過使用絕對路徑或者是相對路徑直接指定這個運行檔檔名,底下的兩個方法都能夠運行ls這個命令:
|
| 例題: 如果我有兩個ls命令在不同的目錄中,例如/usr/local/bin/ls與/bin/ls那么當我下達 ls 的時候,哪個ls會被運行? 答: 那還用說,就找出 PATH 里面哪個目錄先被查詢,則那個目錄下的命令就會被先運行了! |
| 例題: 為什么PATH搜尋的目錄不加入本目錄(.)?加入本目錄的搜尋不是也不錯? 答: 如果在PATH中加入本目錄(.)后,確實我們就能夠在命令所在目錄進行命令的運行了。但是由於你的工作目錄并非固定(常常會使用cd來切換到不同的目錄),因此能夠運行的命令會有變動(因為每個目錄底下的可運行檔都不相同嘛!),這對使用者來說并非好事。 另外,如果有個壞心使用者在/tmp底下做了一個命令,因為/tmp是大家都能夠寫入的環境,所以他當然可以這樣做。假設該命令可能會竊取使用者的一些數據,如果你使用root的身份來運行這個命令,那不是很糟糕?如果這個命令的名稱又是經常會被用到的ls時,那『中標』的機率就更高了! 所以,為了安全起見,不建議將『.』加入PATH的搜尋目錄中。 |
而由上面的幾個例題我們也可以知道幾件事情:
- 不同身份使用者默認的PATH不同,默認能夠隨意運行的命令也不同(如root與vbird);
- PATH是可以修改的,所以一般使用者還是可以透過修改PATH來運行某些位於/sbin或/usr/sbin下的命令來查詢;
- 使用絕對路徑或相對路徑直接指定某個命令的檔名來運行,會比搜尋PATH來的正確;
- 命令應該要放置到正確的目錄下,運行才會比較方便;
- 本目錄(.)最好不要放到PATH當中。
對於PATH更詳細的『變量』說明,我們會在第三篇的bash shell中詳細說明的!
文件與目錄管理:
談了談目錄與路徑之后,再來討論一下關於文件的一些基本管理吧!文件與目錄的管理上,不外乎『顯示屬性』、『拷貝』、『刪除文件』及『移動文件或目錄』等等,由於文件與目錄的管理在 Linux 當中是很重要的,尤其是每個人自己家目錄的數據也都需要注意管理!所以我們來談一談有關文件與目錄的一些基礎管理部分吧!
文件與目錄的檢視: ls
| [root@www ~]# ls [-aAdfFhilnrRSt] 目錄名稱 [root@www ~]# ls [--color={never,auto,always}] 目錄名稱 [root@www ~]# ls [--full-time] 目錄名稱 選項與參數: -a :全部的文件,連同隱藏檔( 開頭為 . 的文件) 一起列出來(常用) -A :全部的文件,連同隱藏檔,但不包括 . 與 .. 這兩個目錄 -d :僅列出目錄本身,而不是列出目錄內的文件數據(常用) -f :直接列出結果,而不進行排序 (ls 默認會以檔名排序!) -F :根據文件、目錄等資訊,給予附加數據結構,例如:*:代表可運行檔; /:代表目錄; =:代表 socket 文件; |:代表 FIFO 文件; -h :將文件容量以人類較易讀的方式(例如 GB, KB 等等)列出來; -i :列出 inode 號碼,inode 的意義下一章將會介紹; -l :長數據串列出,包含文件的屬性與權限等等數據;(常用) -n :列出 UID 與 GID 而非使用者與群組的名稱 (UID與GID會在帳號管理提到!) -r :將排序結果反向輸出,例如:原本檔名由小到大,反向則為由大到小; -R :連同子目錄內容一起列出來,等於該目錄下的所有文件都會顯示出來; -S :以文件容量大小排序,而不是用檔名排序; -t :依時間排序,而不是用檔名。 --color=never :不要依據文件特性給予顏色顯示; --color=always :顯示顏色 --color=auto :讓系統自行依據配置來判斷是否給予顏色 --full-time :以完整時間模式 (包含年、月、日、時、分) 輸出 --time={atime,ctime} :輸出 access 時間或改變權限屬性時間 (ctime) 而非內容變更時間 (modification time) |
在Linux系統當中,這個 ls 命令可能是最常被運行的吧!因為我們隨時都要知道文件或者是目錄的相關資訊啊~不過,我們Linux的文件所記錄的資訊實在是太多了,ls 沒有需要全部都列出來呢~所以,當你只有下達 ls 時,默認顯示的只有:非隱藏檔的檔名、以檔名進行排序及檔名代表的顏色顯示如此而已。舉例來說,你下達『 ls /etc 』之后,只有經過排序的檔名以及以藍色顯示目錄及白色顯示一般文件,如此而已。
那如果我還想要加入其他的顯示資訊時,可以加入上頭提到的那些有用的選項呢~舉例來說,我們之前一直用到的 -l 這個長串顯示數據內容,以及將隱藏檔也一起列示出來的 -a 選項等等。底下則是一些常用的范例,實際試做看看:
| 范例一:將家目錄下的所有文件列出來(含屬性與隱藏檔) [root@www ~]# ls -al ~ total 156 drwxr-x--- 4 root root 4096 Sep 24 00:07 . drwxr-xr-x 23 root root 4096 Sep 22 12:09 .. -rw------- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg -rw------- 1 root root 955 Sep 24 00:08 .bash_history -rw-r--r-- 1 root root 24 Jan 6 2007 .bash_logout -rw-r--r-- 1 root root 191 Jan 6 2007 .bash_profile -rw-r--r-- 1 root root 176 Jan 6 2007 .bashrc drwx------ 3 root root 4096 Sep 5 10:37 .gconf -rw-r--r-- 1 root root 42304 Sep 4 18:26 install.log -rw-r--r-- 1 root root 5661 Sep 4 18:25 install.log.syslog # 這個時候你會看到以 . 為開頭的幾個文件,以及目錄檔 (.) (..) .gconf 等等, # 不過,目錄檔檔名都是以深藍色顯示,有點不容易看清楚就是了。范例二:承上題,不顯示顏色,但在檔名末顯示出該檔名代表的類型(type) [root@www ~]# ls -alF --color=never ~ total 156 drwxr-x--- 4 root root 4096 Sep 24 00:07 ./ drwxr-xr-x 23 root root 4096 Sep 22 12:09 ../ -rw------- 1 root root 1474 Sep 4 18:27 anaconda-ks.cfg -rw------- 1 root root 955 Sep 24 00:08 .bash_history -rw-r--r-- 1 root root 24 Jan 6 2007 .bash_logout -rw-r--r-- 1 root root 191 Jan 6 2007 .bash_profile -rw-r--r-- 1 root root 176 Jan 6 2007 .bashrc drwx------ 3 root root 4096 Sep 5 10:37 .gconf/ -rw-r--r-- 1 root root 42304 Sep 4 18:26 install.log -rw-r--r-- 1 root root 5661 Sep 4 18:25 install.log.syslog # 注意看到顯示結果的第一行,嘿嘿~知道為何我們會下達類似 ./command # 之類的命令了吧?因為 ./ 代表的是『目前目錄下』的意思啊!至於什么是 FIFO/Socket ? # 請參考前一章節的介紹啊!另外,那個.bashrc 時間僅寫2007,能否知道詳細時間?范例三:完整的呈現文件的修改時間 *(modification time) [root@www ~]# ls -al --full-time ~ total 156 drwxr-x--- 4 root root 4096 2008-09-24 00:07:00.000000 +0800 . drwxr-xr-x 23 root root 4096 2008-09-22 12:09:32.000000 +0800 .. -rw------- 1 root root 1474 2008-09-04 18:27:10.000000 +0800 anaconda-ks.cfg -rw------- 1 root root 955 2008-09-24 00:08:14.000000 +0800 .bash_history -rw-r--r-- 1 root root 24 2007-01-06 17:05:04.000000 +0800 .bash_logout -rw-r--r-- 1 root root 191 2007-01-06 17:05:04.000000 +0800 .bash_profile -rw-r--r-- 1 root root 176 2007-01-06 17:05:04.000000 +0800 .bashrc drwx------ 3 root root 4096 2008-09-05 10:37:49.000000 +0800 .gconf -rw-r--r-- 1 root root 42304 2008-09-04 18:26:57.000000 +0800 install.log -rw-r--r-- 1 root root 5661 2008-09-04 18:25:55.000000 +0800 install.log.syslog # 請仔細看,上面的『時間』欄位變了喔!變成較為完整的格式。 # 一般來說, ls -al 僅列出目前短格式的時間,有時不會列出年份, # 藉由 --full-time 可以查閱到比較正確的完整時間格式啊! |
其實 ls 的用法還有很多,包括查閱文件所在 i-node 號碼的 ls -i 選項,以及用來進行文件排序的 -S 選項,還有用來查閱不同時間的動作的 --time=atime 等選項(更多時間說明請參考本章后面touch的說明)。而這些選項的存在都是因為 Linux 文件系統記錄了很多有用的資訊的緣故。那么 Linux 的文件系統中,這些與權限、屬性有關的數據放在哪里呢?放在 i-node 里面。關於這部分,我們會在下一章繼續為你作比較深入的介紹啊!
無論如何, ls 最常被使用到的功能還是那個 -l 的選項,為此,很多 distribution 在默認的情況中,已經將 ll (L 的小寫) 配置成為 ls -l 的意思了!其實,那個功能是Bash shell 的alias功能呢~也就是說,我們直接輸入 ll 就等於是輸入 ls -l 是一樣的~關於這部分,我們會在后續 bash shell時再次的強調滴~
復制、刪除與移動: cp, rm, mv
要復制文件,請使用 cp (copy) 這個命令即可~不過, cp 這個命令的用途可多了~除了單純的復制之外,還可以創建連結檔 (就是捷徑羅),比對兩文件的新舊而予以升級,以及復制整個目錄等等的功能呢!至於移動目錄與文件,則使用 mv (move),這個命令也可以直接拿來作更名 (rename) 的動作喔!至於移除嗎?那就是 rm (remove)這個命令羅~底下我們就來瞧一瞧先~
- cp (復制文件或目錄)
| [root@www ~]# cp [-adfilprsu] 來源檔(source) 目標檔(destination) [root@www ~]# cp [options] source1 source2 source3 .... directory 選項與參數: -a :相當於 -pdr 的意思,至於 pdr 請參考下列說明;(常用) -d :若來源檔為連結檔的屬性(link file),則復制連結檔屬性而非文件本身; -f :為強制(force)的意思,若目標文件已經存在且無法開啟,則移除后再嘗試一次; -i :若目標檔(destination)已經存在時,在覆蓋時會先詢問動作的進行(常用) -l :進行硬式連結(hard link)的連結檔創建,而非復制文件本身; -p :連同文件的屬性一起復制過去,而非使用默認屬性(備份常用); -r :遞回持續復制,用於目錄的復制行為;(常用) -s :復制成為符號連結檔 (symbolic link),亦即『捷徑』文件; -u :若 destination 比 source 舊才升級 destination ! 最后需要注意的,如果來源檔有兩個以上,則最后一個目的檔一定要是『目錄』才行! |
復制(cp)這個命令是非常重要的,不同身份者運行這個命令會有不同的結果產生,尤其是那個-a, -p的選項,對於不同身份來說,差異則非常的大!底下的練習中,有的身份為root有的身份為一般帳號(在我這里用vbird這個帳號),練習時請特別注意身份的差別喔!好!開始來做復制的練習與觀察:
| 范例一:用root身份,將家目錄下的 .bashrc 復制到 /tmp 下,并更名為 bashrc [root@www ~]# cp ~/.bashrc /tmp/bashrc [root@www ~]# cp -i ~/.bashrc /tmp/bashrc cp: overwrite `/tmp/bashrc'? n <==n不覆蓋,y為覆蓋 # 重復作兩次動作,由於 /tmp 底下已經存在 bashrc 了,加上 -i 選項后, # 則在覆蓋前會詢問使用者是否確定!可以按下 n 或者 y 來二次確認呢!范例二:變換目錄到/tmp,并將/var/log/wtmp復制到/tmp且觀察屬性: [root@www ~]# cd /tmp [root@www tmp]# cp /var/log/wtmp . <==想要復制到目前的目錄,最后的 . 不要忘 [root@www tmp]# ls -l /var/log/wtmp wtmp -rw-rw-r-- 1 root utmp 96384 Sep 24 11:54 /var/log/wtmp -rw-r--r-- 1 root root 96384 Sep 24 14:06 wtmp # 注意上面的特殊字體,在不加任何選項的情況下,文件的某些屬性/權限會改變; # 這是個很重要的特性!要注意喔!還有,連文件創建的時間也不一樣了! # 那如果你想要將文件的所有特性都一起復制過來該怎辦?可以加上 -a 喔!如下所示:[root@www tmp]# cp -a /var/log/wtmp wtmp_2 [root@www tmp]# ls -l /var/log/wtmp wtmp_2 -rw-rw-r-- 1 root utmp 96384 Sep 24 11:54 /var/log/wtmp -rw-rw-r-- 1 root utmp 96384 Sep 24 11:54 wtmp_2 # 了了吧!整個數據特性完全一模一樣ㄟ!真是不賴~這就是 -a 的特性! |
這個 cp 的功能很多,由於我們常常會進行一些數據的復制,所以也會常常用到這個命令的。一般來說,我們如果去復制別人的數據 (當然,該文件你必須要有 read 的權限才行啊! ^_^) 時,總是希望復制到的數據最后是我們自己的,所以,在默認的條件中, cp 的來源檔與目的檔的權限是不同的,目的檔的擁有者通常會是命令操作者本身。舉例來說,上面的范例二中,由於我是 root 的身份,因此復制過來的文件擁有者與群組就改變成為 root 所有了!這樣說,可以明白嗎?^_^
由於具有這個特性,因此當我們在進行備份的時候,某些需要特別注意的特殊權限文件,例如密碼檔 (/etc/shadow) 以及一些配置檔,就不能直接以 cp 來復制,而必須要加上 -a 或者是 -p 等等可以完整復制文件權限的選項才行!另外,如果你想要復制文件給其他的使用者,也必須要注意到文件的權限(包含讀、寫、運行以及文件擁有者等等),否則,其他人還是無法針對你給予的文件進行修訂的動作喔!注意注意!
| 范例三:復制 /etc/ 這個目錄下的所有內容到 /tmp 底下 [root@www tmp]# cp /etc/ /tmp cp: omitting directory `/etc' <== 如果是目錄則不能直接復制,要加上 -r 的選項 [root@www tmp]# cp -r /etc/ /tmp # 還是要再次的強調喔! -r 是可以復制目錄,但是,文件與目錄的權限可能會被改變 # 所以,也可以利用『 cp -a /etc /tmp 』來下達命令喔!尤其是在備份的情況下!范例四:將范例一復制的 bashrc 創建一個連結檔 (symbolic link) [root@www tmp]# ls -l bashrc -rw-r--r-- 1 root root 176 Sep 24 14:02 bashrc <==先觀察一下文件情況 [root@www tmp]# cp -s bashrc bashrc_slink [root@www tmp]# cp -l bashrc bashrc_hlink [root@www tmp]# ls -l bashrc* -rw-r--r-- 2 root root 176 Sep 24 14:02 bashrc <==與原始文件不太一樣了! -rw-r--r-- 2 root root 176 Sep 24 14:02 bashrc_hlink lrwxrwxrwx 1 root root 6 Sep 24 14:20 bashrc_slink -> bashrc |
范例四可有趣了!使用 -l 及 -s 都會創建所謂的連結檔(link file),但是這兩種連結檔卻有不一樣的情況。這是怎么一回事啊?那個 -l 就是所謂的實體連結(hard link),至於 -s 則是符號連結(symbolic link),簡單來說,bashrc_slink 是一個『捷徑』,這個捷徑會連結到bashrc去!所以你會看到檔名右側會有個指向(->)的符號!
至於bashrc_hlink文件與bashrc的屬性與權限完全一模一樣,與尚未進行連結前的差異則是第二欄的link數由1變成2了!鳥哥這里先不介紹實體連結,因為實體連結涉及 i-node 的相關知識,我們下一章談到文件系統(filesystem)時再來討論這個問題。
| 范例五:若 ~/.bashrc 比 /tmp/bashrc 新才復制過來 [root@www tmp]# cp -u ~/.bashrc /tmp/bashrc # 這個 -u 的特性,是在目標文件與來源文件有差異時,才會復制的。 # 所以,比較常被用於『備份』的工作當中喔! ^_^范例六:將范例四造成的 bashrc_slink 復制成為 bashrc_slink_1 與bashrc_slink_2 [root@www tmp]# cp bashrc_slink bashrc_slink_1 [root@www tmp]# cp -d bashrc_slink bashrc_slink_2 [root@www tmp]# ls -l bashrc bashrc_slink* -rw-r--r-- 2 root root 176 Sep 24 14:02 bashrc lrwxrwxrwx 1 root root 6 Sep 24 14:20 bashrc_slink -> bashrc -rw-r--r-- 1 root root 176 Sep 24 14:32 bashrc_slink_1 <==與原始文件相同 lrwxrwxrwx 1 root root 6 Sep 24 14:33 bashrc_slink_2 -> bashrc <==是連結檔! # 這個例子也是很有趣喔!原本復制的是連結檔,但是卻將連結檔的實際文件復制過來了 # 也就是說,如果沒有加上任何選項時,cp復制的是原始文件,而非連結檔的屬性! # 若要復制連結檔的屬性,就得要使用 -d 的選項了!如 bashrc_slink_2 所示。范例七:將家目錄的 .bashrc 及 .bash_history 復制到 /tmp 底下 [root@www tmp]# cp ~/.bashrc ~/.bash_history /tmp # 可以將多個數據一次復制到同一個目錄去!最后面一定是目錄! |
例題: 你能否使用vbird的身份,完整的復制/var/log/wtmp文件到/tmp底下,并更名為vbird_wtmp呢? 答: 實際做看看的結果如下:
|
總之,由於 cp 有種種的文件屬性與權限的特性,所以,在復制時,你必須要清楚的了解到:
- 是否需要完整的保留來源文件的資訊?
- 來源文件是否為連結檔 (symbolic link file)?
- 來源檔是否為特殊的文件,例如 FIFO, socket 等?
- 來源檔是否為目錄?
- rm (移除文件或目錄)
| [root@www ~]# rm [-fir] 文件或目錄 選項與參數: -f :就是 force 的意思,忽略不存在的文件,不會出現警告信息; -i :互動模式,在刪除前會詢問使用者是否動作 -r :遞回刪除啊!最常用在目錄的刪除了!這是非常危險的選項!!!范例一:將剛剛在 cp 的范例中創建的 bashrc 刪除掉! [root@www ~]# cd /tmp [root@www tmp]# rm -i bashrc rm: remove regular file `bashrc'? y # 如果加上 -i 的選項就會主動詢問喔,避免你刪除到錯誤的檔名!范例二:透過萬用字節*的幫忙,將/tmp底下開頭為bashrc的檔名通通刪除: [root@www tmp]# rm -i bashrc* # 注意那個星號,代表的是 0 到無窮多個任意字節喔!很好用的東西!范例三:將 cp 范例中所創建的 /tmp/etc/ 這個目錄刪除掉! [root@www tmp]# rmdir /tmp/etc rmdir: etc: Directory not empty <== 刪不掉啊!因為這不是空的目錄! [root@www tmp]# rm -r /tmp/etc rm: descend into directory `/tmp/etc'? y ....(中間省略).... # 因為身份是 root ,默認已經加入了 -i 的選項,所以你要一直按 y 才會刪除! # 如果不想要繼續按 y ,可以按下『 [ctrl]-c 』來結束 rm 的工作。 # 這是一種保護的動作,如果確定要刪除掉此目錄而不要詢問,可以這樣做: [root@www tmp]# \rm -r /tmp/etc # 在命令前加上反斜線,可以忽略掉 alias 的指定選項喔!至於 alias 我們在bash再談!范例四:刪除一個帶有 - 開頭的文件 [root@www tmp]# touch ./-aaa- <==touch這個命令可以創建空文件! [root@www tmp]# ls -l -rw-r--r-- 1 root root 0 Sep 24 15:03 -aaa- <==文件大小為0,所以是空文件 [root@www tmp]# rm -aaa- Try `rm --help' for more information. <== 因為 "-" 是選項嘛!所以系統誤判了! [root@www tmp]# rm ./-aaa- |
這是移除的命令(remove),要注意的是,通常在Linux系統下,為了怕文件被誤殺,所以很多 distributions 都已經默認加入 -i 這個選項了!而如果要連目錄下的東西都一起殺掉的話,例如子目錄里面還有子目錄時,那就要使用 -r 這個選項了!不過,使用『 rm -r 』這個命令之前,請千萬注意了,因為該目錄或文件『肯定』會被 root 殺掉!因為系統不會再次詢問你是否要砍掉呦!所以那是個超級嚴重的命令下達呦!得特別注意!不過,如果你確定該目錄不要了,那么使用 rm -r 來循環殺掉是不錯的方式!
另外,范例四也是很有趣的例子,我們在之前就談過,檔名最好不要使用 "-" 號開頭,因為 "-" 后面接的是選項,因此,單純的使用『 rm -aaa- 』系統的命令就會誤判啦!那如果使用后面會談到的正規表示法時,還是會出問題的!所以,只能用避過首位字節是 "-" 的方法啦!就是加上本目錄『 ./ 』即可!如果 man rm 的話,其實還有一種方法,那就是『 rm -- -aaa- 』也可以啊!- mv (移動文件與目錄,或更名)
| [root@www ~]# mv [-fiu] source destination [root@www ~]# mv [options] source1 source2 source3 .... directory 選項與參數: -f :force 強制的意思,如果目標文件已經存在,不會詢問而直接覆蓋; -i :若目標文件 (destination) 已經存在時,就會詢問是否覆蓋! -u :若目標文件已經存在,且 source 比較新,才會升級 (update)范例一:復制一文件,創建一目錄,將文件移動到目錄中 [root@www ~]# cd /tmp [root@www tmp]# cp ~/.bashrc bashrc [root@www tmp]# mkdir mvtest [root@www tmp]# mv bashrc mvtest # 將某個文件移動到某個目錄去,就是這樣做!范例二:將剛剛的目錄名稱更名為 mvtest2 [root@www tmp]# mv mvtest mvtest2 <== 這樣就更名了!簡單~ # 其實在 Linux 底下還有個有趣的命令,名稱為 rename , # 該命令專職進行多個檔名的同時更名,并非針對單一檔名變更,與mv不同。請man rename。范例三:再創建兩個文件,再全部移動到 /tmp/mvtest2 當中 [root@www tmp]# cp ~/.bashrc bashrc1 [root@www tmp]# cp ~/.bashrc bashrc2 [root@www tmp]# mv bashrc1 bashrc2 mvtest2 # 注意到這邊,如果有多個來源文件或目錄,則最后一個目標檔一定是『目錄!』 # 意思是說,將所有的數據移動到該目錄的意思! |
這是搬移 (move) 的意思!當你要移動文件或目錄的時后,呵呵!這個命令就很重要啦!同樣的,你也可以使用 -u ( update )來測試新舊文件,看看是否需要搬移羅!另外一個用途就是『變更檔名!』,我們可以很輕易的使用 mv 來變更一個文件的檔名呢!不過,在 Linux 才有的命令當中,有個 rename ,可以用來更改大量文件的檔名,你可以利用 man rename 來查閱一下,也是挺有趣的命令喔!
取得路徑的文件名稱與目錄名稱
我們前面介紹的完整檔名 (包含目錄名稱與文件名稱) 當中提到,完整檔名最長可以到達 4096 個字節。那么你怎么知道那個是檔名?那個是目錄名?嘿嘿!就是利用斜線 (/) 來分辨啊!其實,取得檔名或者是目錄名稱,一般的用途應該是在寫程序的時候,用來判斷之用的啦~所以,這部分的命令可以用在第三篇內的 shell scripts 里頭喔!底下我們簡單的以幾個范例來談一談 basename 與 dirname 的用途!
| [root@www ~]# basename /etc/sysconfig/network network <== 很簡單!就取得最后的檔名~ [root@www ~]# dirname /etc/sysconfig/network /etc/sysconfig <== 取得的變成目錄名了! |
文件內容查閱:
如果我們要查閱一個文件的內容時,該如何是好呢?這里有相當多有趣的命令可以來分享一下:最常使用的顯示文件內容的命令可以說是 cat 與 more 及 less 了!此外,如果我們要查看一個很大型的文件 (好幾百MB時),但是我們只需要后端的幾行字而已,那么該如何是好?呵呵!用 tail 呀,此外, tac 這個命令也可以達到!好了,說說各個命令的用途吧!
- cat? 由第一行開始顯示文件內容
- tac? 從最后一行開始顯示,可以看出 tac 是 cat 的倒著寫!
- nl ??顯示的時候,順道輸出行號!
- more 一頁一頁的顯示文件內容
- less 與 more 類似,但是比 more 更好的是,他可以往前翻頁!
- head 只看頭幾行
- tail 只看尾巴幾行
- od?? 以二進位的方式讀取文件內容!
直接檢視文件內容
直接查閱一個文件的內容可以使用 cat/tac/nl 這幾個命令啊!
- cat (concatenate)
| [root@www ~]# cat [-AbEnTv] 選項與參數: -A :相當於 -vET 的整合選項,可列出一些特殊字符而不是空白而已; -b :列出行號,僅針對非空白行做行號顯示,空白行不標行號! -E :將結尾的斷行字節 $ 顯示出來; -n :列印出行號,連同空白行也會有行號,與 -b 的選項不同; -T :將 [tab] 按鍵以 ^I 顯示出來; -v :列出一些看不出來的特殊字符范例一:檢閱 /etc/issue 這個文件的內容 [root@www ~]# cat /etc/issue CentOS release 5.3 (Final) Kernel \r on an \m范例二:承上題,如果還要加印行號呢? [root@www ~]# cat -n /etc/issue1 CentOS release 5.3 (Final)2 Kernel \r on an \m3 # 看到了吧!可以印出行號呢!這對於大文件要找某個特定的行時,有點用處! # 如果不想要編排空白行的行號,可以使用『cat -b /etc/issue』,自己測試看看:范例三:將 /etc/xinetd.conf 的內容完整的顯示出來(包含特殊字節) [root@www ~]# cat -A /etc/xinetd.conf #$ ....(中間省略).... $ defaults$ {$ # The next two items are intended to be a quick access place to$ ....(中間省略).... ^Ilog_type^I= SYSLOG daemon info $ ^Ilog_on_failure^I= HOST$ ^Ilog_on_success^I= PID HOST DURATION EXIT$ ....(中間省略).... includedir /etc/xinetd.d$$ # 上面的結果限於篇幅,鳥哥刪除掉很多數據了。另外,輸出的結果并不會有特殊字體, # 鳥哥上面的特殊字體是要讓您發現差異點在哪里就是了。基本上,在一般的環境中, # 使用 [tab] 與空白鍵的效果差不多,都是一堆空白啊!我們無法知道兩者的差別。 # 此時使用 cat -A 就能夠發現那些空白的地方是啥鬼東西了![tab]會以 ^I 表示, # 斷行字節則是以 $ 表示,所以你可以發現每一行后面都是 $ 啊!不過斷行字節 # 在Windows/Linux則不太相同,Windows的斷行字節是 ^M$ 羅。 # 這部分我們會在第十章 vim 軟件的介紹時,再次的說明到喔! |
嘿嘿!Linux 里面有『貓』命令?喔!不是的, cat 是 Concatenate (連續)的簡寫,主要的功能是將一個文件的內容連續的印出在螢幕上面!例如上面的例子中,我們將 /etc/issue 印出來!如果加上 -n 或 -b 的話,則每一行前面還會加上行號呦!
鳥哥個人是比較少用 cat 啦!畢竟當你的文件內容的行數超過 40 行以上,嘿嘿!根本來不及在螢幕上看到結果!所以,配合等一下要介紹的 more 或者是 less 來運行比較好!此外,如果是一般的 DOS 文件時,就需要特別留意一些奇奇怪怪的符號了,例如斷行與 [tab] 等,要顯示出來,就得加入 -A 之類的選項了!
- tac (反向列示)
| [root@www ~]# tac /etc/issueKernel \r on an \m CentOS release 5.3 (Final) # 嘿嘿!與剛剛上面的范例一比較,是由最后一行先顯示喔! |
tac 這個好玩了!怎么說呢?詳細的看一下, cat 與 tac ,有沒有發現呀!對啦! tac 剛好是將 cat 反寫過來,所以他的功能就跟 cat 相反啦, cat 是由『第一行到最后一行連續顯示在螢幕上』,而 tac 則是『由最后一行到第一行反向在螢幕上顯示出來 』,很好玩吧!
- nl (添加行號列印)
| [root@www ~]# nl [-bnw] 文件 選項與參數: -b :指定行號指定的方式,主要有兩種:-b a :表示不論是否為空行,也同樣列出行號(類似 cat -n);-b t :如果有空行,空的那一行不要列出行號(默認值); -n :列出行號表示的方法,主要有三種:-n ln :行號在螢幕的最左方顯示;-n rn :行號在自己欄位的最右方顯示,且不加 0 ;-n rz :行號在自己欄位的最右方顯示,且加 0 ; -w :行號欄位的占用的位數。范例一:用 nl 列出 /etc/issue 的內容 [root@www ~]# nl /etc/issue1 CentOS release 5.3 (Final)2 Kernel \r on an \m# 注意看,這個文件其實有三行,第三行為空白(沒有任何字節), # 因為他是空白行,所以 nl 不會加上行號喔!如果確定要加上行號,可以這樣做:[root@www ~]# nl -b a /etc/issue1 CentOS release 5.3 (Final)2 Kernel \r on an \m3 # 呵呵!行號加上來羅~那么如果要讓行號前面自動補上 0 呢?可這樣[root@www ~]# nl -b a -n rz /etc/issue 000001 CentOS release 5.3 (Final) 000002 Kernel \r on an \m 000003 # 嘿嘿!自動在自己欄位的地方補上 0 了~默認欄位是六位數,如果想要改成 3 位數?[root@www ~]# nl -b a -n rz -w 3 /etc/issue 001 CentOS release 5.3 (Final) 002 Kernel \r on an \m 003 # 變成僅有 3 位數羅~ |
nl 可以將輸出的文件內容自動的加上行號!其默認的結果與 cat -n 有點不太一樣,nl 可以將行號做比較多的顯示設計,包括位數與是否自動補齊 0 等等的功能呢。
可翻頁檢視
前面提到的 nl 與 cat, tac 等等,都是一次性的將數據一口氣顯示到螢幕上面,那有沒有可以進行一頁一頁翻動的命令啊?讓我們可以一頁一頁的觀察,才不會前面的數據看不到啊~呵呵!有的!那就是 more 與 less 羅~
- more (一頁一頁翻動)
| [root@www ~]# more /etc/man.config # # Generated automatically from man.conf.in by the # configure script. # # man.conf from man-1.6d ....(中間省略).... --More--(28%) <== 重點在這一行喔!你的光標也會在這里等待你的命令 |
仔細的給他看到上面的范例,如果 more 后面接的文件內容行數大於螢幕輸出的行數時,就會出現類似上面的圖示。重點在最后一行,最后一行會顯示出目前顯示的百分比,而且還可以在最后一行輸入一些有用的命令喔!在 more 這個程序的運行過程中,你有幾個按鍵可以按的:
- 空白鍵 (space):代表向下翻一頁;
- Enter???????? :代表向下翻『一行』;
- /字串???????? :代表在這個顯示的內容當中,向下搜尋『字串』這個關鍵字;
- :f??????????? :立刻顯示出檔名以及目前顯示的行數;
- q???????????? :代表立刻離開 more ,不再顯示該文件內容。
- b 或 [ctrl]-b :代表往回翻頁,不過這動作只對文件有用,對管線無用。
要離開 more 這個命令的顯示工作,可以按下 q 就能夠離開了。而要向下翻頁,就使用空白鍵即可。比較有用的是搜尋字串的功能,舉例來說,我們使用『 more /etc/man.config 』來觀察該文件,若想要在該文件內搜尋 MANPATH 這個字串時,可以這樣做:
| [root@www ~]# more /etc/man.config # # Generated automatically from man.conf.in by the # configure script. # # man.conf from man-1.6d ....(中間省略).... /MANPATH <== 輸入了 / 之后,光標就會自動跑到最底下一行等待輸入! |
如同上面的說明,輸入了 / 之后,光標就會跑到最底下一行,并且等待你的輸入,你輸入了字串并按下[enter]之后,嘿嘿! more 就會開始向下搜尋該字串羅~而重復搜尋同一個字串,可以直接按下 n 即可啊!最后,不想要看了,就按下 q 即可離開 more 啦!
- less (一頁一頁翻動)
| [root@www ~]# less /etc/man.config # # Generated automatically from man.conf.in by the # configure script. # # man.conf from man-1.6d ....(中間省略).... : <== 這里可以等待你輸入命令! |
less 的用法比起 more 又更加的有彈性,怎么說呢?在 more 的時候,我們并沒有辦法向前面翻,只能往后面看,但若使用了 less 時,呵呵!就可以使用 [pageup] [pagedown] 等按鍵的功能來往前往后翻看文件,你瞧,是不是更容易使用來觀看一個文件的內容了呢!
除此之外,在 less 里頭可以擁有更多的『搜尋』功能喔!不止可以向下搜尋,也可以向上搜尋~實在是很不錯用~基本上,可以輸入的命令有:
- 空白鍵????:向下翻動一頁;
- [pagedown]:向下翻動一頁;
- [pageup]??:向上翻動一頁;
- /字串?????:向下搜尋『字串』的功能;
- ?字串?????:向上搜尋『字串』的功能;
- n???????? :重復前一個搜尋 (與 / 或 ? 有關!)
- N???????? :反向的重復前一個搜尋 (與 / 或 ? 有關!)
- q???????? :離開 less 這個程序;
查閱文件內容還可以進行搜尋的動作~瞧~ less 是否很不錯用啊!其實 less 還有很多的功能喔!詳細的使用方式請使用 man less 查詢一下啊! ^_^
你是否會覺得 less 使用的畫面與環境與 man page非常的類似呢?沒錯啦!因為man這個命令就是呼叫 less 來顯示說明文件的內容的!現在你是否覺得 less 很重要呢? ^_^
數據擷取
我們可以將輸出的數據作一個最簡單的擷取,那就是取出前面 (head) 與取出后面 (tail) 文字的功能。不過,要注意的是, head 與 tail 都是以『行』為單位來進行數據擷取的喔!
- head (取出前面幾行)
| [root@www ~]# head [-n number] 文件 選項與參數: -n :后面接數字,代表顯示幾行的意思[root@www ~]# head /etc/man.config # 默認的情況中,顯示前面十行!若要顯示前 20 行,就得要這樣: [root@www ~]# head -n 20 /etc/man.config范例:如果后面100行的數據都不列印,只列印/etc/man.config的前面幾行,該如何是好? [root@www ~]# head -n -100 /etc/man.config |
head 的英文意思就是『頭』啦,那么這個東西的用法自然就是顯示出一個文件的前幾行羅!沒錯!就是這樣!若沒有加上 -n 這個選項時,默認只顯示十行,若只要一行呢?那就加入『 head -n 1 filename 』即可!
另外那個 -n 選項后面的參數較有趣,如果接的是負數,例如上面范例的-n -100時,代表列前的所有行數,但不包括后面100行。舉例來說,/etc/man.config共有141行,則上述的命令『head -n -100 /etc/man.config』就會列出前面41行,后面100行不會列印出來了。這樣說,比較容易懂了吧? ^_^
- tail (取出后面幾行)
| [root@www ~]# tail [-n number] 文件 選項與參數: -n :后面接數字,代表顯示幾行的意思 -f :表示持續偵測后面所接的檔名,要等到按下[ctrl]-c才會結束tail的偵測[root@www ~]# tail /etc/man.config # 默認的情況中,顯示最后的十行!若要顯示最后的 20 行,就得要這樣: [root@www ~]# tail -n 20 /etc/man.config范例一:如果不知道/etc/man.config有幾行,卻只想列出100行以后的數據時? [root@www ~]# tail -n +100 /etc/man.config范例二:持續偵測/var/log/messages的內容 [root@www ~]# tail -f /var/log/messages<==要等到輸入[crtl]-c之后才會離開tail這個命令的偵測! |
有 head 自然就有 tail ( 尾巴 ) 羅!沒錯!這個 tail 的用法跟 head 的用法差不多類似,只是顯示的是后面幾行就是了!默認也是顯示十行,若要顯示非十行,就加 -n number 的選項即可。
范例一的內容就有趣啦!其實與head -n -xx有異曲同工之妙。當下達『tail -n +100 /etc/man.config』代表該文件從100行以后都會被列出來,同樣的,在man.config共有141行,因此第100~141行就會被列出來啦!前面的99行都不會被顯示出來喔!
至於范例二中,由於/var/log/messages隨時會有數據寫入,你想要讓該文件有數據寫入時就立刻顯示到螢幕上,就利用 -f 這個選項,他可以一直偵測/var/log/messages這個文件,新加入的數據都會被顯示到螢幕上。直到你按下[crtl]-c才會離開tail的偵測喔!
| 例題: 假如我想要顯示 /etc/man.config 的第 11 到第 20 行呢? 答: 這個應該不算難,想一想,在第 11 到第 20 行,那么我取前 20 行,再取后十行,所以結果就是:『 head -n 20 /etc/man.config | tail -n 10 』,這樣就可以得到第 11 到第 20 行之間的內容了!但是里面涉及到管線命令,需要在第三篇的時候才講的到! |
非純文字檔: od
我們上面提到的,都是在查閱純文字檔的內容。那么萬一我們想要查閱非文字檔,舉例來說,例如 /usr/bin/passwd 這個運行檔的內容時,又該如何去讀出資訊呢?事實上,由於運行檔通常是 binary file ,使用上頭提到的命令來讀取他的內容時,確實會產生類似亂碼的數據啊!那怎么辦?沒關系,我們可以利用 od 這個命令來讀取喔!
| [root@www ~]# od [-t TYPE] 文件 選項或參數: -t :后面可以接各種『類型 (TYPE)』的輸出,例如:a :利用默認的字節來輸出;c :使用 ASCII 字節來輸出d[size] :利用十進位(decimal)來輸出數據,每個整數占用 size bytes ;f[size] :利用浮點數值(floating)來輸出數據,每個數占用 size bytes ;o[size] :利用八進位(octal)來輸出數據,每個整數占用 size bytes ;x[size] :利用十六進位(hexadecimal)來輸出數據,每個整數占用 size bytes ;范例一:請將/usr/bin/passwd的內容使用ASCII方式來展現! [root@www ~]# od -t c /usr/bin/passwd 0000000 177 E L F 001 001 001 \0 \0 \0 \0 \0 \0 \0 \0 \0 0000020 002 \0 003 \0 001 \0 \0 \0 260 225 004 \b 4 \0 \0 \0 0000040 020 E \0 \0 \0 \0 \0 \0 4 \0 \0 \a \0 ( \0 0000060 035 \0 034 \0 006 \0 \0 \0 4 \0 \0 \0 4 200 004 \b 0000100 4 200 004 \b 340 \0 \0 \0 340 \0 \0 \0 005 \0 \0 \0 .....(后面省略).... # 最左邊第一欄是以 8 進位來表示bytes數。以上面范例來說,第二欄0000020代表開頭是 # 第 16 個 byes (2x8) 的內容之意。范例二:請將/etc/issue這個文件的內容以8進位列出儲存值與ASCII的對照表 [root@www ~]# od -t oCc /etc/issue 0000000 103 145 156 164 117 123 040 162 145 154 145 141 163 145 040 065C e n t O S r e l e a s e 5 0000020 056 062 040 050 106 151 156 141 154 051 012 113 145 162 156 145. 2 ( F i n a l ) \n K e r n e 0000040 154 040 134 162 040 157 156 040 141 156 040 134 155 012 012l \ r o n a n \ m \n \n 0000057 # 如上所示,可以發現每個字節可以對應到的數值為何! # 例如e對應的記錄數值為145,轉成十進位:1x8^2+4x8+5=101。 |
利用這個命令,可以將 data file 或者是 binary file 的內容數據給他讀出來喔!雖然讀出的來數值默認是使用非文字檔,亦即是 16 進位的數值來顯示的,不過,我們還是可以透過 -t c 的選項與參數來將數據內的字節以 ASCII 類型的字節來顯示,雖然對於一般使用者來說,這個命令的用處可能不大,但是對於工程師來說,這個命令可以將 binary file 的內容作一個大致的輸出,他們可以看得出東西的啦~ ^_^
如果對純文字檔使用這個命令,你甚至可以發現到 ASCII 與字節的對照表!非常有趣!例如上述的范例二,你可以發現到每個英文字 e 對照到的數字都是 145,轉成十進位你就能夠發現那是 101 羅!如果你有任何程序語言的書,拿出來對照一下 ASCII 的對照表,就能夠發現真是正確啊!呵呵!
修改文件時間或建置新檔: touch
我們在 ls 這個命令的介紹時,有稍微提到每個文件在linux底下都會記錄許多的時間參數,其實是有三個主要的變動時間,那么三個時間的意義是什么呢?
- modification time (mtime):
當該文件的『內容數據』變更時,就會升級這個時間!內容數據指的是文件的內容,而不是文件的屬性或權限喔!
- status time (ctime):
當該文件的『狀態 (status)』改變時,就會升級這個時間,舉例來說,像是權限與屬性被更改了,都會升級這個時間啊。
- access time (atime):
當『該文件的內容被取用』時,就會升級這個讀取時間 (access)。舉例來說,我們使用 cat 去讀取 /etc/man.config ,就會升級該文件的 atime 了。
這是個挺有趣的現象,舉例來說,我們來看一看你自己的 /etc/man.config 這個文件的時間吧!
| [root@www ~]# ls -l /etc/man.config -rw-r--r-- 1 root root 4617 Jan 6 2007 /etc/man.config [root@www ~]# ls -l --time=atime /etc/man.config -rw-r--r-- 1 root root 4617 Sep 25 17:54 /etc/man.config [root@www ~]# ls -l --time=ctime /etc/man.config -rw-r--r-- 1 root root 4617 Sep 4 18:03 /etc/man.config |
看到了嗎?在默認的情況下,ls 顯示出來的是該文件的mtime ,也就是這個文件的內容上次被更動的時間。至於鳥哥的系統是在 9 月 4 號的時候安裝的,因此,這個文件被產生導致狀態被更動的時間就回溯到那個時間點了(ctime)!而還記得剛剛我們使用的范例當中,有使用到man.config這個文件啊,所以啊,他的 atime 就會變成剛剛使用的時間了!
文件的時間是很重要的,因為,如果文件的時間誤判的話,可能會造成某些程序無法順利的運行。OK!那么萬一我發現了一個文件來自未來,該如何讓該文件的時間變成『現在』的時刻呢?很簡單啊!就用『touch』這個命令即可!
| Tips: 嘿嘿!不要懷疑系統時間會『來自未來』喔!很多時候會有這個問題的!舉例來說在安裝過后系統時間可能會被改變!因為臺灣時區在國際標準時間『格林威治時間, GMT』的右邊,所以會比較早看到陽光,也就是說,臺灣時間比GMT時間快了八小時!如果安裝行為不當,我們的系統可能會有八小時快轉,你的文件就有可能來自八小時后了。 至於某些情況下,由於BIOS的配置錯誤,導致系統時間跑到未來時間,并且你又創建了某些文件。等你將時間改回正確的時間時,該文件不就變成來自未來了?^_^ |
| [root@www ~]# touch [-acdmt] 文件 選項與參數: -a :僅修訂 access time; -c :僅修改文件的時間,若該文件不存在則不創建新文件; -d :后面可以接欲修訂的日期而不用目前的日期,也可以使用 --date="日期或時間" -m :僅修改 mtime ; -t :后面可以接欲修訂的時間而不用目前的時間,格式為[YYMMDDhhmm]范例一:新建一個空的文件并觀察時間 [root@www ~]# cd /tmp [root@www tmp]# touch testtouch [root@www tmp]# ls -l testtouch -rw-r--r-- 1 root root 0 Sep 25 21:09 testtouch # 注意到,這個文件的大小是 0 呢!在默認的狀態下,如果 touch 后面有接文件, # 則該文件的三個時間 (atime/ctime/mtime) 都會升級為目前的時間。若該文件不存在, # 則會主動的創建一個新的空的文件喔!例如上面這個例子!范例二:將 ~/.bashrc 復制成為 bashrc,假設復制完全的屬性,檢查其日期 [root@www tmp]# cp -a ~/.bashrc bashrc [root@www tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc -rw-r--r-- 1 root root 176 Jan 6 2007 bashrc <==這是 mtime -rw-r--r-- 1 root root 176 Sep 25 21:11 bashrc <==這是 atime -rw-r--r-- 1 root root 176 Sep 25 21:12 bashrc <==這是 ctime |
在上面這個案例當中我們使用了『ll』這個命令(兩個英文L的小寫),這個命令其實就是『ls -l』的意思,ll本身不存在,是被『做出來』的一個命令別名。相關的命令別名我們會在bash章節當中詳談的,這里先知道ll="ls -l"即可。至於分號『 ; 』則代表連續命令的下達啦!你可以在一行命令當中寫入多重命令,這些命令可以『依序』運行。由上面的命令我們會知道ll那一行有三個命令被下達在同一行中。
至於運行的結果當中,我們可以發現數據的內容與屬性是被復制過來的,因此文件內容時間(mtime)與原本文件相同。但是由於這個文件是剛剛被創建的,因此狀態(ctime)與讀取時間就便呈現在的時間啦!那如果你想要變更這個文件的時間呢?可以這樣做:
| 范例三:修改案例二的 bashrc 文件,將日期調整為兩天前 [root@www tmp]# touch -d "2 days ago" bashrc [root@www tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc -rw-r--r-- 1 root root 176 Sep 23 21:23 bashrc -rw-r--r-- 1 root root 176 Sep 23 21:23 bashrc -rw-r--r-- 1 root root 176 Sep 25 21:23 bashrc # 跟上個范例比較看看,本來是 25 日的變成了 23 日了 (atime/mtime)~ # 不過, ctime 并沒有跟著改變喔!范例四:將上個范例的 bashrc 日期改為 2007/09/15 2:02 [root@www tmp]# touch -t 0709150202 bashrc [root@www tmp]# ll bashrc; ll --time=atime bashrc; ll --time=ctime bashrc -rw-r--r-- 1 root root 176 Sep 15 2007 bashrc -rw-r--r-- 1 root root 176 Sep 15 2007 bashrc -rw-r--r-- 1 root root 176 Sep 25 21:25 bashrc # 注意看看,日期在 atime 與 mtime 都改變了,但是 ctime 則是記錄目前的時間! |
透過 touch 這個命令,我們可以輕易的修訂文件的日期與時間。并且也可以創建一個空的文件喔!不過,要注意的是,即使我們復制一個文件時,復制所有的屬性,但也沒有辦法復制 ctime 這個屬性的。ctime 可以記錄這個文件最近的狀態 (status) 被改變的時間。無論如何,還是要告知大家,我們平時看的文件屬性中,比較重要的還是屬於那個 mtime 啊!我們關心的常常是這個文件的『內容』是什么時候被更動的說~了乎?
無論如何, touch 這個命令最常被使用的情況是:
- 創建一個空的文件;
- 將某個文件日期修訂為目前 (mtime 與 atime)
文件與目錄的默認權限與隱藏權限
由第六章、Linux文件權限的內容我們可以知道一個文件有若干個屬性,包括讀寫運行(r, w, x)等基本權限,及是否為目錄 (d) 與文件 (-) 或者是連結檔 (l) 等等的屬性!要修改屬性的方法在前面也約略提過了(chgrp,chown,chmod),本小節會再加強補充一下!
除了基本r, w, x權限外,在Linux的Ext2/Ext3文件系統下,我們還可以配置其他的系統隱藏屬性,這部份可使用 chattr 來配置,而以 lsattr 來查看,最重要的屬性就是可以配置其不可修改的特性!讓連文件的擁有者都不能進行修改!這個屬性可是相當重要的,尤其是在安全機制上面 (security)!
首先,先來復習一下上一章談到的權限概念,將底下的例題看一看先:
| 例題: 你的系統有個一般身份使用者 dmtsai,他的群組屬於 users,他的家目錄在 /home/dmtsai,你是root,你想將你的 ~/.bashrc 復制給他,可以怎么作? 答: 由上一章的權限概念我們可以知道 root 雖然可以將這個文件復制給 dmtsai,不過這個文件在 dmtsai的家目錄中卻可能讓 dmtsai 沒有辦法讀寫(因為該文件屬於 root 的嘛!而 dmtsai 又不能使用 chown 之故)。此外,我們又擔心覆蓋掉 dmtsai 自己的 .bashrc 配置檔,因此,我們可以進行如下的動作喔: 復制文件: cp ~/.bashrc ~dmtsai/bashrc 修改屬性: chown dmtsai:users ~dmtsai/bashrc |
| 例題: 我想在 /tmp 底下創建一個目錄,這個目錄名稱為 chapter7_1 ,并且這個目錄擁有者為 dmtsai,群組為 users ,此外,任何人都可以進入該目錄瀏覽文件,不過除了 dmtsai 之外,其他人都不能修改該目錄下的文件。 答: 因為除了 dmtsai 之外,其他人不能修改該目錄下的文件,所以整個目錄的權限應該是 drwxr-xr-x 才對!因此你應該這樣做: 創建目錄: mkdir /tmp/chapter7_1 修改屬性: chown -R dmtsai:users /tmp/chapter7_1 修改權限: chmod -R 755 /tmp/chapter7_1 |
在上面這個例題當中,如果你知道 755 那個分數是怎么計算出來的,那么你應該對於權限有一定程度的概念了。如果你不知道 755 怎么來的?那么...趕快回去前一章看看chmod 那個命令的介紹部分啊!這部分很重要喔!你得要先清楚的了解到才行~否則就進行不下去羅~假設你對於權限都認識的差不多了,那么底下我們就要來談一談,『新增一個文件或目錄時,默認的權限是什么?』這個議題!
文件默認權限:umask
OK!那么現在我們知道如何創建或者是改變一個目錄或文件的屬性了,不過,你知道當你創建一個新的文件或目錄時,他的默認權限會是什么嗎?呵呵!那就與 umask 這個玩意兒有關了!那么 umask 是在搞什么呢?基本上, umask 就是指定『目前使用者在創建文件或目錄時候的權限默認值』,那么如何得知或配置 umask 呢?他的指定條件以底下的方式來指定:
| [root@www ~]# umask 0022 <==與一般權限有關的是后面三個數字! [root@www ~]# umask -S u=rwx,g=rx,o=rx |
查閱的方式有兩種,一種可以直接輸入 umask ,就可以看到數字型態的權限配置分數,一種則是加入 -S (Symbolic) 這個選項,就會以符號類型的方式來顯示出權限了!奇怪的是,怎么 umask 會有四組數字啊?不是只有三組嗎?是沒錯啦。第一組是特殊權限用的,我們先不要理他,所以先看后面三組即可。
在默認權限的屬性上,目錄與文件是不一樣的。從第六章我們知道 x 權限對於目錄是非常重要的!但是一般文件的創建則不應該有運行的權限,因為一般文件通常是用在於數據的記錄嘛!當然不需要運行的權限了。因此,默認的情況如下:
- 若使用者創建為『文件』則默認『沒有可運行( x )權限』,亦即只有 rw 這兩個項目,也就是最大為 666 分,默認權限如下:
-rw-rw-rw-
- 若使用者創建為『目錄』,則由於 x 與是否可以進入此目錄有關,因此默認為所有權限均開放,亦即為 777 分,默認權限如下:
drwxrwxrwx
要注意的是,umask 的分數指的是『該默認值需要減掉的權限!』因為 r、w、x 分別是 4、2、1 分,所以羅!也就是說,當要拿掉能寫的權限,就是輸入 2 分,而如果要拿掉能讀的權限,也就是 4 分,那么要拿掉讀與寫的權限,也就是 6 分,而要拿掉運行與寫入的權限,也就是 3 分,這樣了解嗎?請問你, 5 分是什么?呵呵!就是讀與運行的權限啦!
如果以上面的例子來說明的話,因為 umask 為 022 ,所以 user 并沒有被拿掉任何權限,不過 group 與 others 的權限被拿掉了 2 (也就是 w 這個權限),那么當使用者:
- 創建文件時:(-rw-rw-rw-) - (-----w--w-) ==> -rw-r--r--
- 創建目錄時:(drwxrwxrwx) - (d----w--w-) ==> drwxr-xr-x
| [root@www ~]# umask 0022 [root@www ~]# touch test1 [root@www ~]# mkdir test2 [root@www ~]# ll -rw-r--r-- 1 root root 0 Sep 27 00:25 test1 drwxr-xr-x 2 root root 4096 Sep 27 00:25 test2 |
呵呵!瞧見了吧!確定新建文件的權限是沒有錯的。
- umask的利用與重要性:專題制作
想像一個狀況,如果你跟你的同學在同一部主機里面工作時,因為你們兩個正在進行同一個專題,老師也幫你們兩個的帳號創建好了相同群組的狀態,并且將 /home/class/ 目錄做為你們兩個人的專題目錄。想像一下,有沒有可能你所制作的文件你的同學無法編輯?果真如此的話,那就傷腦筋了!
這個問題很常發生啊!舉上面的案例來看就好了,你看一下 test1 的權限是幾分? 644 呢!意思是『如果 umask 訂定為 022 ,那新建的數據只有使用者自己具有 w 的權限,同群組的人只有 r 這個可讀的權限而已,并無法修改喔!』這樣要怎么共同制作專題啊!您說是吧!
所以,當我們需要新建文件給同群組的使用者共同編輯時,那么 umask 的群組就不能拿掉 2 這個 w 的權限!所以羅, umask 就得要是 002 之類的才可以!這樣新建的文件才能夠是 -rw-rw-r-- 的權限模樣喔!那么如何配置 umask 呢?簡單的很,直接在 umask 后面輸入 002 就好了!
| [root@www ~]# umask 002 [root@www ~]# touch test3 [root@www ~]# mkdir test4 [root@www ~]# ll -rw-rw-r-- 1 root root 0 Sep 27 00:36 test3 drwxrwxr-x 2 root root 4096 Sep 27 00:36 test4 |
所以說,這個 umask 對於新建文件與目錄的默認權限是很有關系的!這個概念可以用在任何服務器上面,尤其是未來在你架設文件服務器 (file server) ,舉例來說,SAMBA Server 或者是FTP server 時,都是很重要的觀念!這牽涉到你的使用者是否能夠將文件進一步利用的問題喔!不要等閑視之!
| 例題: 假設你的 umask 為 003 ,請問該 umask 情況下,創建的文件與目錄權限為? 答: umask 為 003 ,所以拿掉的權限為 --------wx,因此: 文件: (-rw-rw-rw-) - (--------wx) = -rw-rw-r-- 目錄: (drwxrwxrwx) - (--------wx) = drwxrwxr-- |
| Tips: 關於 umask 與權限的計算方式中,教科書喜歡使用二進位的方式來進行 AND 與 NOT 的計算,不過,鳥哥還是比較喜歡使用符號方式來計算~聯想上面比較容易一點~ 但是,有的書籍或者是 BBS 上面的朋友,喜歡使用文件默認屬性 666 與目錄默認屬性777 來與 umask 進行相減的計算~這是不好的喔!以上面例題來看,如果使用默認屬性相加減,則文件變成:666-003=663,亦即是 -rw-rw--wx ,這可是完全不對的喔!想想看,原本文件就已經去除 x 的默認屬性了,怎么可能突然間冒出來了?所以,這個地方得要特別小心喔! |
在默認的情況中, root 的 umask 會拿掉比較多的屬性,root 的 umask 默認是 022 ,這是基於安全的考量啦~至於一般身份使用者,通常他們的 umask 為 002 ,亦即保留同群組的寫入權力!其實,關於默認 umask 的配置可以參考 /etc/bashrc 這個文件的內容,不過,不建議修改該文件,你可以參考第十一章 bash shell 提到的環境參數配置檔(~/.bashrc) 的說明!
文件隱藏屬性:
什么?文件還有隱藏屬性?光是那九個權限就快要瘋掉了,竟然還有隱藏屬性,真是要命~但是沒辦法,就是有文件的隱藏屬性存在啊!不過,這些隱藏的屬性確實對於系統有很大的幫助的~尤其是在系統安全 (Security) 上面,重要的緊呢!不過要先強調的是,底下的chattr命令只能在Ext2/Ext3的文件系統上面生效,其他的文件系統可能就無法支持這個命令了。底下我們就來談一談如何配置與檢查這些隱藏的屬性吧!
- chattr (配置文件隱藏屬性)
| [root@www ~]# chattr [+-=][ASacdistu] 文件或目錄名稱 選項與參數: + :添加某一個特殊參數,其他原本存在參數則不動。 - :移除某一個特殊參數,其他原本存在參數則不動。 = :配置一定,且僅有后面接的參數A :當配置了 A 這個屬性時,若你有存取此文件(或目錄)時,他的存取時間 atime將不會被修改,可避免I/O較慢的機器過度的存取磁碟。這對速度較慢的計算機有幫助 S :一般文件是非同步寫入磁碟的(原理請參考第五章sync的說明),如果加上 S 這個屬性時,當你進行任何文件的修改,該更動會『同步』寫入磁碟中。 a :當配置 a 之后,這個文件將只能添加數據,而不能刪除也不能修改數據,只有root 才能配置這個屬性。 c :這個屬性配置之后,將會自動的將此文件『壓縮』,在讀取的時候將會自動解壓縮,但是在儲存的時候,將會先進行壓縮后再儲存(看來對於大文件似乎蠻有用的!) d :當 dump 程序被運行的時候,配置 d 屬性將可使該文件(或目錄)不會被 dump 備份 i :這個 i 可就很厲害了!他可以讓一個文件『不能被刪除、改名、配置連結也無法寫入或新增數據!』對於系統安全性有相當大的助益!只有 root 能配置此屬性 s :當文件配置了 s 屬性時,如果這個文件被刪除,他將會被完全的移除出這個硬盤空間,所以如果誤刪了,完全無法救回來了喔! u :與 s 相反的,當使用 u 來配置文件時,如果該文件被刪除了,則數據內容其實還存在磁碟中,可以使用來救援該文件喔! 注意:屬性配置常見的是 a 與 i 的配置值,而且很多配置值必須要身為 root 才能配置范例:請嘗試到/tmp底下創建文件,并加入 i 的參數,嘗試刪除看看。 [root@www ~]# cd /tmp [root@www tmp]# touch attrtest <==創建一個空文件 [root@www tmp]# chattr +i attrtest <==給予 i 的屬性 [root@www tmp]# rm attrtest <==嘗試刪除看看 rm: remove write-protected regular empty file `attrtest'? y rm: cannot remove `attrtest': Operation not permitted <==操作不許可 # 看到了嗎?呼呼!連 root 也沒有辦法將這個文件刪除呢!趕緊解除配置!范例:請將該文件的 i 屬性取消! [root@www tmp]# chattr -i attrtest |
這個命令是很重要的,尤其是在系統的數據安全上面!由於這些屬性是隱藏的性質,所以需要以 lsattr 才能看到該屬性呦!其中,個人認為最重要的當屬 +i 與 +a這個屬性了。+i 可以讓一個文件無法被更動,對於需要強烈的系統安全的人來說,真是相當的重要的!里頭還有相當多的屬性是需要 root 才能配置的呢!
此外,如果是 log file 這種的登錄檔,就更需要 +a 這個可以添加,但是不能修改舊有的數據與刪除的參數了!怎樣?很棒吧!未來提到登錄檔 (十九章) 的認知時,我們再來聊一聊如何配置他吧!
- lsattr (顯示文件隱藏屬性)
| [root@www ~]# lsattr [-adR] 文件或目錄 選項與參數: -a :將隱藏檔的屬性也秀出來; -d :如果接的是目錄,僅列出目錄本身的屬性而非目錄內的檔名; -R :連同子目錄的數據也一并列出來! [root@www tmp]# chattr +aij attrtest [root@www tmp]# lsattr attrtest ----ia---j--- attrtest |
使用 chattr 配置后,可以利用 lsattr 來查閱隱藏的屬性。不過,這兩個命令在使用上必須要特別小心,否則會造成很大的困擾。例如:某天你心情好,突然將 /etc/shadow 這個重要的密碼記錄文件給他配置成為具有 i 的屬性,那么過了若干天之后,你突然要新增使用者,卻一直無法新增!別懷疑,趕快去將 i 的屬性拿掉吧!
文件特殊權限:SUID, SGID, SBIT
我們前面一直提到關於文件的重要權限,那就是 rwx 這三個讀、寫、運行的權限。但是,眼尖的朋友們在第六章的目錄樹章節中,一定注意到了一件事,那就是,怎么我們的 /tmp 權限怪怪的?還有,那個 /usr/bin/passwd 也怪怪的?怎么回事啊?看看先:
| [root@www ~]# ls -ld /tmp ; ls -l /usr/bin/passwd drwxrwxrwt 7 root root 4096 Sep 27 18:23 /tmp -rwsr-xr-x 1 root root 22984 Jan 7 2007 /usr/bin/passwd |
不是應該只有 rwx 嗎?還有其他的特殊權限( s 跟 t )啊?啊.....頭又開始昏了~ @_@因為 s 與 t 這兩個權限的意義與系統的帳號 (第十四章)及系統的程序(process, 第十七章)較為相關,所以等到后面的章節談完后你才會比較有概念!底下的說明先看看就好,如果看不懂也沒有關系,先知道s放在哪里稱為SUID/SGID以及如何配置即可,等系統程序章節讀完后,再回來看看喔!
- Set UID
當 s 這個標志出現在文件擁有者的 x 權限上時,例如剛剛提到的 /usr/bin/passwd 這個文件的權限狀態:『-rwsr-xr-x』,此時就被稱為 Set UID,簡稱為 SUID 的特殊權限。那么SUID的權限對於一個文件的特殊功能是什么呢?基本上SUID有這樣的限制與功能:
- SUID 權限僅對二進位程序(binary program)有效;
- 運行者對於該程序需要具有 x 的可運行權限;
- 本權限僅在運行該程序的過程中有效 (run-time);
- 運行者將具有該程序擁有者 (owner) 的權限。
講這么硬的東西你可能對於 SUID 還是沒有概念,沒關系,我們舉個例子來說明好了。我們的 Linux 系統中,所有帳號的密碼都記錄在 /etc/shadow 這個文件里面,這個文件的權限為:『-r-------- 1 root root』,意思是這個文件僅有root可讀且僅有root可以強制寫入而已。既然這個文件僅有 root 可以修改,那么鳥哥的 vbird 這個一般帳號使用者能否自行修改自己的密碼呢?你可以使用你自己的帳號輸入『passwd』這個命令來看看,嘿嘿!一般使用者當然可以修改自己的密碼了!
唔!有沒有沖突啊!明明 /etc/shadow 就不能讓 vbird 這個一般帳戶去存取的,為什么 vbird 還能夠修改這個文件內的密碼呢?這就是 SUID 的功能啦!藉由上述的功能說明,我們可以知道
但如果 vbird 使用 cat 去讀取 /etc/shadow 時,他能夠讀取嗎?因為 cat 不具有 SUID 的權限,所以 vbird 運行 『cat /etc/shadow』時,是不能讀取 /etc/shadow 的。我們用一張示意圖來說明如下:
圖4.4.1、SUID程序運行的過程示意圖
另外,SUID 僅可用在binary program 上,不能夠用在 shell script 上面!這是因為 shell script 只是將很多的 binary 運行檔叫進來運行而已!所以 SUID 的權限部分,還是得要看 shell script 呼叫進來的程序的配置,而不是 shell script 本身。當然,SUID 對於目錄也是無效的~這點要特別留意。
- Set GID
當 s 標志在文件擁有者的 x 項目為 SUID,那 s 在群組的 x 時則稱為 Set GID, SGID 羅!是這樣沒錯!^_^。舉例來說,你可以用底下的命令來觀察到具有 SGID 權限的文件喔:
| [root@www ~]# ls -l /usr/bin/locate -rwx--s--x 1 root slocate 23856 Mar 15 2007 /usr/bin/locate |
與 SUID 不同的是,SGID 可以針對文件或目錄來配置!如果是對文件來說, SGID 有如下的功能:
- SGID 對二進位程序有用;
- 程序運行者對於該程序來說,需具備 x 的權限;
- 運行者在運行的過程中將會獲得該程序群組的支持!
舉例來說,上面的 /usr/bin/locate 這個程序可以去搜尋 /var/lib/mlocate/mlocate.db 這個文件的內容 (詳細說明會在下節講述),mlocate.db 的權限如下:
| [root@www ~]# ll /usr/bin/locate /var/lib/mlocate/mlocate.db -rwx--s--x 1 root slocate 23856 Mar 15 2007 /usr/bin/locate -rw-r----- 1 root slocate 3175776 Sep 28 04:02 /var/lib/mlocate/mlocate.db |
與 SUID 非常的類似,若我使用 vbird 這個帳號去運行 locate 時,那 vbird 將會取得 slocate 群組的支持,因此就能夠去讀取 mlocate.db 啦!非常有趣吧!
除了 binary program 之外,事實上 SGID 也能夠用在目錄上,這也是非常常見的一種用途!當一個目錄配置了 SGID 的權限后,他將具有如下的功能:
- 使用者若對於此目錄具有 r 與 x 的權限時,該使用者能夠進入此目錄;
- 使用者在此目錄下的有效群組(effective group)將會變成該目錄的群組;
- 用途:若使用者在此目錄下具有 w 的權限(可以新建文件),則使用者所創建的新文件,該新文件的群組與此目錄的群組相同。
SGID 對於專案開發來說是非常重要的!因為這涉及群組權限的問題,您可以參考一下本章后續情境模擬的案例,應該就能夠對於 SGID 有一些了解的!^_^
- Sticky Bit
這個 Sticky Bit, SBIT 目前只針對目錄有效,對於文件已經沒有效果了。SBIT 對於目錄的作用是:
- 當使用者對於此目錄具有 w, x 權限,亦即具有寫入的權限時;
- 當使用者在該目錄下創建文件或目錄時,僅有自己與 root 才有權力刪除該文件
換句話說:當甲這個使用者於 A 目錄是具有群組或其他人的身份,并且擁有該目錄 w 的權限,這表示『甲使用者對該目錄內任何人創建的目錄或文件均可進行 "刪除/更名/搬移" 等動作。』不過,如果將 A 目錄加上了 SBIT 的權限項目時,則甲只能夠針對自己創建的文件或目錄進行刪除/更名/移動等動作,而無法刪除他人的文件。
舉例來說,我們的 /tmp 本身的權限是『drwxrwxrwt』,在這樣的權限內容下,任何人都可以在 /tmp 內新增、修改文件,但僅有該文件/目錄創建者與 root 能夠刪除自己的目錄或文件。這個特性也是挺重要的啊!你可以這樣做個簡單的測試:
由於 SUID/SGID/SBIT 牽涉到程序的概念,因此再次強調,這部份的數據在您讀完第十七章關於程序方面的知識后,要再次的回來瞧瞧喔!目前,你先有個簡單的基礎概念就好了!文末的參考數據也建議閱讀一番喔!
- SUID/SGID/SBIT 權限配置
前面介紹過 SUID 與 SGID 的功能,那么如何配置文件使成為具有 SUID 與 SGID 的權限呢?這就需要第六章的數字更改權限的方法了!現在你應該已經知道數字型態更改權限的方式為『三個數字』的組合,那么如果在這三個數字之前再加上一個數字的話,最前面的那個數字就代表這幾個權限了!
- 4 為 SUID
- 2 為 SGID
- 1 為 SBIT
假設要將一個文件權限改為『-rwsr-xr-x』時,由於 s 在使用者權限中,所以是 SUID ,因此,在原先的 755 之前還要加上 4 ,也就是:『 chmod 4755 filename 』來配置!此外,還有大 S 與大 T 的產生喔!參考底下的范例啦!
| Tips: 注意:底下的范例只是練習而已,所以鳥哥使用同一個文件來配置,你必須了解SUID 不是用在目錄上,而 SBIT 不是用在文件上的喔! |
| [root@www ~]# cd /tmp [root@www tmp]# touch test <==創建一個測試用空檔 [root@www tmp]# chmod 4755 test; ls -l test <==加入具有 SUID 的權限 -rwsr-xr-x 1 root root 0 Sep 29 03:06 test [root@www tmp]# chmod 6755 test; ls -l test <==加入具有 SUID/SGID 的權限 -rwsr-sr-x 1 root root 0 Sep 29 03:06 test [root@www tmp]# chmod 1755 test; ls -l test <==加入 SBIT 的功能! -rwxr-xr-t 1 root root 0 Sep 29 03:06 test [root@www tmp]# chmod 7666 test; ls -l test <==具有空的 SUID/SGID 權限 -rwSrwSrwT 1 root root 0 Sep 29 03:06 test |
最后一個例子就要特別小心啦!怎么會出現大寫的 S 與 T 呢?不都是小寫的嗎?因為 s 與 t 都是取代 x 這個權限的,但是你有沒有發現阿,我們是下達 7666 喔!也就是說,user, group 以及 others 都沒有 x 這個可運行的標志( 因為 666 嘛 ),所以,這個 S, T 代表的就是『空的』啦!怎么說? SUID 是表示『該文件在運行的時候,具有文件擁有者的權限』,但是文件擁有者都無法運行了,哪里來的權限給其他人使用?當然就是空的啦! ^_^
而除了數字法之外,你也可以透過符號法來處理喔!其中 SUID 為 u+s ,而 SGID 為 g+s ,SBIT則是 o+t 羅!來看看如下的范例:
| # 配置權限成為 -rws--x--x 的模樣: [root@www tmp]# chmod u=rwxs,go=x test; ls -l test -rws--x--x 1 root root 0 Aug 18 23:47 test# 承上,加上 SGID 與 SBIT 在上述的文件權限中! [root@www tmp]# chmod g+s,o+t test; ls -l test -rws--s--t 1 root root 0 Aug 18 23:47 test |
觀察文件類型:file
如果你想要知道某個文件的基本數據,例如是屬於 ASCII 或者是 data 文件,或者是 binary ,且其中有沒有使用到動態函式庫 (share library) 等等的資訊,就可以利用 file 這個命令來檢閱喔!舉例來說:
| [root@www ~]# file ~/.bashrc /root/.bashrc: ASCII text <==告訴我們是 ASCII 的純文字檔啊! [root@www ~]# file /usr/bin/passwd /usr/bin/passwd: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped # 運行檔的數據可就多的不得了!包括這個文件的 suid 權限、兼容於 Intel 386 # 等級的硬件平臺、使用的是 Linux 核心 2.6.9 的動態函式庫連結等等。 [root@www ~]# file /var/lib/mlocate/mlocate.db /var/lib/mlocate/mlocate.db: data <== 這是 data 文件! |
透過這個命令,我們可以簡單的先判斷這個文件的格式為何喔!
命令與文件的搜尋:
文件的搜尋可就厲害了!因為我們常常需要知道那個文件放在哪里,才能夠對該文件進行一些修改或維護等動作。有些時候某些軟件配置檔的檔名是不變的,但是各 distribution 放置的目錄則不同。此時就得要利用一些搜尋命令將該配置檔的完整檔名捉出來,這樣才能修改嘛!您說是吧!^_^
命令檔名的搜尋:
我們知道在終端機模式當中,連續輸入兩次[tab]按鍵就能夠知道使用者有多少命令可以下達。那你知不知道這些命令的完整檔名放在哪里?舉例來說,ls 這個常用的命令放在哪里呢?就透過 which 或 type 來找尋吧!
- which (尋找『運行檔』)
| [root@www ~]# which [-a] command 選項或參數: -a :將所有由 PATH 目錄中可以找到的命令均列出,而不止第一個被找到的命令名稱范例一:分別用root與一般帳號搜尋 ifconfig 這個命令的完整檔名 [root@www ~]# which ifconfig /sbin/ifconfig <==用 root 可以找到正確的運行檔名喔! [root@www ~]# su - vbird <==切換身份成為 vbird 去! [vbird@www ~]$ which ifconfig /usr/bin/which: no ifconfig in (/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin :/home/vbird/bin) <==見鬼了!竟然一般身份帳號找不到! # 因為 which 是根據使用者所配置的 PATH 變量內的目錄去搜尋可運行檔的!所以, # 不同的 PATH 配置內容所找到的命令當然不一樣啦!因為 /sbin 不在 vbird 的 # PATH 中,找不到也是理所當然的啊!了乎? [vbird@www ~]$ exit <==記得將身份切換回原本的 root范例二:用 which 去找出 which 的檔名為何? [root@www ~]# which which alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot '/usr/bin/which # 竟然會有兩個 which ,其中一個是 alias 這玩意兒呢!那是啥? # 那就是所謂的『命令別名』,意思是輸入 which 會等於后面接的那串命令啦! # 更多的數據我們會在 bash 章節中再來談的!范例三:請找出 cd 這個命令的完整檔名 [root@www ~]# which cd /usr/bin/which: no cd in (/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin :/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin) # 瞎密?怎么可能沒有 cd ,我明明就能夠用 root 運行 cd 的啊! |
這個命令是根據『PATH』這個環境變量所規范的路徑,去搜尋『運行檔』的檔名~所以,重點是找出『運行檔』而已!且 which 后面接的是『完整檔名』喔!若加上 -a選項,則可以列出所有的可以找到的同名運行檔,而非僅顯示第一個而已!
最后一個范例最有趣,怎么 cd 這個常用的命令竟然找不到啊!為什么呢?這是因為 cd 是『bash 內建的命令』啦!但是 which 默認是找 PATH 內所規范的目錄,所以當然一定找不到的啊!那怎辦?沒關系!我們可以透過 type 這個命令喔!關於 type 的用法我們將在第十一章的 bash 再來談!
文件檔名的搜尋:
再來談一談怎么搜尋文件吧!在 Linux 底下也有相當優異的搜尋命令呦!通常 find 不很常用的!因為速度慢之外,也很操硬盤!通常我們都是先使用 whereis 或者是 locate 來檢查,如果真的找不到了,才以 find 來搜尋呦!為什么呢?因為 whereis 與 locate 是利用數據庫來搜尋數據,所以相當的快速,而且并沒有實際的搜尋硬盤,比較省時間啦!
- whereis (尋找特定文件)
| [root@www ~]# whereis [-bmsu] 文件或目錄名 選項與參數: -b :只找 binary 格式的文件 -m :只找在說明檔 manual 路徑下的文件 -s :只找 source 來源文件 -u :搜尋不在上述三個項目當中的其他特殊文件范例一:請用不同的身份找出 ifconfig 這個檔名 [root@www ~]# whereis ifconfig ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz [root@www ~]# su - vbird <==切換身份成為 vbird [vbird@www ~]$ whereis ifconfig <==找到同樣的結果喔! ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz [vbird@www ~]$ exit <==回歸身份成為 root 去! # 注意看,明明 which 一般使用者找不到的 ifconfig 卻可以讓 whereis 找到! # 這是因為系統真的有 ifconfig 這個『文件』,但是使用者的 PATH 并沒有加入 /sbin # 所以,未來你找不到某些命令時,先用文件搜尋命令找找看再說!范例二:只找出跟 passwd 有關的『說明文件』檔名(man page) [root@www ~]# whereis -m passwd passwd: /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz |
等一下我們會提到 find 這個搜尋命令, find 是很強大的搜尋命令,但時間花用的很大!(因為 find 是直接搜尋硬盤,為如果你的硬盤比較老舊的話,嘿嘿!有的等!) 這個時候 whereis 就相當的好用了!另外, whereis 可以加入選項來找尋相關的數據,例如如果你是要找可運行檔( binary )那么加上 -b 就可以啦!如果不加任何選項的話,那么就將所有的數據列出來羅!
那么 whereis 到底是使用什么咚咚呢?為何搜尋的速度會比 find 快這么多?其實那也沒有什么!這是因為 Linux 系統會將系統內的所有文件都記錄在一個數據庫文件里面,而當使用 whereis 或者是底下要說的 locate 時,都會以此數據庫文件的內容為準,因此,有的時后你還會發現使用這兩個運行檔時,會找到已經被殺掉的文件!而且也找不到最新的剛剛創建的文件呢!這就是因為這兩個命令是由數據庫當中的結果去搜尋文件的所在啊!更多與這個數據庫有關的說明,請參考下列的 locate 命令。
- locate
| [root@www ~]# locate [-ir] keyword 選項與參數: -i :忽略大小寫的差異; -r :后面可接正規表示法的顯示方式范例一:找出系統中所有與 passwd 相關的檔名 [root@www ~]# locate passwd /etc/passwd /etc/passwd- /etc/news/passwd.nntp /etc/pam.d/passwd ....(底下省略).... |
這個 locate 的使用更簡單,直接在后面輸入『文件的部分名稱』后,就能夠得到結果。舉上面的例子來說,我輸入 locate passwd ,那么在完整檔名 (包含路徑名稱) 當中,只要有 passwd 在其中,就會被顯示出來的!這也是個很方便好用的命令,如果你忘記某個文件的完整檔名時~~
但是,這個東西還是有使用上的限制呦!為什么呢?你會發現使用 locate 來尋找數據的時候特別的快,這是因為 locate 尋找的數據是由『已創建的數據庫 /var/lib/mlocate/』里面的數據所搜尋到的,所以不用直接在去硬盤當中存取數據,呵呵!當然是很快速羅!
那么有什么限制呢?就是因為他是經由數據庫來搜尋的,而數據庫的創建默認是在每天運行一次(每個 distribution 都不同,CentOS 5.x 是每天升級數據庫一次!),所以當你新創建起來的文件,卻還在數據庫升級之前搜尋該文件,那么 locate 會告訴你『找不到!』呵呵!因為必須要升級數據庫呀!
那能否手動升級數據庫哪?當然可以啊!升級 locate 數據庫的方法非常簡單,直接輸入『 updatedb 』就可以了!updatedb 命令會去讀取 /etc/updatedb.conf 這個配置檔的配置,然后再去硬盤里面進行搜尋檔名的動作,最后就升級整個數據庫文件羅!因為 updatedb 會去搜尋硬盤,所以當你運行 updatedb 時,可能會等待數分鐘的時間喔!
- updatedb:根據 /etc/updatedb.conf 的配置去搜尋系統硬盤內的檔名,并升級 /var/lib/mlocate 內的數據庫文件;
- locate:依據 /var/lib/mlocate 內的數據庫記載,找出使用者輸入的關鍵字檔名。
- find
| [root@www ~]# find [PATH] [option] [action] 選項與參數: 1. 與時間有關的選項:共有 -atime, -ctime 與 -mtime ,以 -mtime 說明-mtime n :n 為數字,意義為在 n 天之前的『一天之內』被更動過內容的文件;-mtime +n :列出在 n 天之前(不含 n 天本身)被更動過內容的文件檔名;-mtime -n :列出在 n 天之內(含 n 天本身)被更動過內容的文件檔名。-newer file :file 為一個存在的文件,列出比 file 還要新的文件檔名范例一:將過去系統上面 24 小時內有更動過內容 (mtime) 的文件列出 [root@www ~]# find / -mtime 0 # 那個 0 是重點!0 代表目前的時間,所以,從現在開始到 24 小時前, # 有變動過內容的文件都會被列出來!那如果是三天前的 24 小時內? # find / -mtime 3 有變動過的文件都被列出的意思!范例二:尋找 /etc 底下的文件,如果文件日期比 /etc/passwd 新就列出 [root@www ~]# find /etc -newer /etc/passwd # -newer 用在分辨兩個文件之間的新舊關系是很有用的! |
時間參數真是挺有意思的!我們現在知道 atime, ctime 與 mtime 的意義,如果你想要找出一天內被更動過的文件名稱,可以使用上述范例一的作法。但如果我想要找出『4天內被更動過的文件檔名』呢?那可以使用『find /var -mtime -4 』。那如果是『4天前的那一天』就用『find /var -mtime 4 』。有沒有加上『+, -』差別很大喔!我們可以用簡單的圖示來說明一下:
圖5.2.1、find 相關的時間參數意義
圖中最右邊為目前的時間,越往左邊則代表越早之前的時間軸啦。由圖5.2.1我們可以清楚的知道:
- +4代表大於等於5天前的檔名:ex> find /var -mtime +4
- -4代表小於等於4天內的文件檔名:ex> find /var -mtime -4
- 4則是代表4-5那一天的文件檔名:ex> find /var -mtime 4
非常有趣吧!你可以在 /var/ 目錄下搜尋一下,感受一下輸出文件的差異喔!再來看看其他 find 的用法吧!
| 選項與參數: 2. 與使用者或群組名稱有關的參數:-uid n :n 為數字,這個數字是使用者的帳號 ID,亦即 UID ,這個 UID 是記錄在/etc/passwd 里面與帳號名稱對應的數字。這方面我們會在第四篇介紹。-gid n :n 為數字,這個數字是群組名稱的 ID,亦即 GID,這個 GID 記錄在/etc/group,相關的介紹我們會第四篇說明~-user name :name 為使用者帳號名稱喔!例如 dmtsai -group name:name 為群組名稱喔,例如 users ;-nouser :尋找文件的擁有者不存在 /etc/passwd 的人!-nogroup :尋找文件的擁有群組不存在於 /etc/group 的文件!當你自行安裝軟件時,很可能該軟件的屬性當中并沒有文件擁有者,這是可能的!在這個時候,就可以使用 -nouser 與 -nogroup 搜尋。范例三:搜尋 /home 底下屬於 vbird 的文件 [root@www ~]# find /home -user vbird # 這個東西也很有用的~當我們要找出任何一個使用者在系統當中的所有文件時, # 就可以利用這個命令將屬於某個使用者的所有文件都找出來喔!范例四:搜尋系統中不屬於任何人的文件 [root@www ~]# find / -nouser # 透過這個命令,可以輕易的就找出那些不太正常的文件。 # 如果有找到不屬於系統任何人的文件時,不要太緊張, # 那有時候是正常的~尤其是你曾經以原始碼自行編譯軟件時。 |
如果你想要找出某個使用者在系統底下創建了啥咚咚,使用上述的選項與參數,就能夠找出來啦!至於那個 -nouser 或 -nogroup 的選項功能中,除了你自行由網絡上面下載文件時會發生之外,如果你將系統里面某個帳號刪除了,但是該帳號已經在系統內創建很多文件時,就可能會發生無主孤魂的文件存在!此時你就得使用這個 -nouser 來找出該類型的文件羅!
| 選項與參數: 3. 與文件權限及名稱有關的參數:-name filename:搜尋文件名稱為 filename 的文件;-size [+-]SIZE:搜尋比 SIZE 還要大(+)或小(-)的文件。這個 SIZE 的規格有:c: 代表 byte, k: 代表 1024bytes。所以,要找比 50KB還要大的文件,就是『 -size +50k 』-type TYPE :搜尋文件的類型為 TYPE 的,類型主要有:一般正規文件 (f),裝置文件 (b, c), 目錄 (d), 連結檔 (l), socket (s), 及 FIFO (p) 等屬性。-perm mode :搜尋文件權限『剛好等於』 mode 的文件,這個 mode 為類似 chmod的屬性值,舉例來說, -rwsr-xr-x 的屬性為 4755 !-perm -mode :搜尋文件權限『必須要全部囊括 mode 的權限』的文件,舉例來說,我們要搜尋 -rwxr--r-- ,亦即 0744 的文件,使用 -perm -0744,當一個文件的權限為 -rwsr-xr-x ,亦即 4755 時,也會被列出來,因為 -rwsr-xr-x 的屬性已經囊括了 -rwxr--r-- 的屬性了。-perm +mode :搜尋文件權限『包含任一 mode 的權限』的文件,舉例來說,我們搜尋-rwxr-xr-x ,亦即 -perm +755 時,但一個文件屬性為 -rw-------也會被列出來,因為他有 -rw.... 的屬性存在!范例五:找出檔名為 passwd 這個文件 [root@www ~]# find / -name passwd # 利用這個 -name 可以搜尋檔名啊!范例六:找出 /var 目錄下,文件類型為 Socket 的檔名有哪些? [root@www ~]# find /var -type s # 這個 -type 的屬性也很有幫助喔!尤其是要找出那些怪異的文件, # 例如 socket 與 FIFO 文件,可以用 find /var -type p 或 -type s 來找!范例七:搜尋文件當中含有 SGID 或 SUID 或 SBIT 的屬性 [root@www ~]# find / -perm +7000 # 所謂的 7000 就是 ---s--s--t ,那么只要含有 s 或 t 的就列出, # 所以當然要使用 +7000 ,使用 -7000 表示要含有 ---s--s--t 的所有三個權限, # 因此,就是 +7000 ~了乎? |
上述范例中比較有趣的就屬 -perm 這個選項啦!他的重點在找出特殊權限的文件羅!我們知道 SUID 與 SGID 都可以配置在二進位程序上,假設我想要找出來 /bin, /sbin 這兩個目錄下,只要具有 SUID 或 SGID 就列出來該文件,你可以這樣做:
| [root@www ~]# find /bin /sbin -perm +6000 |
因為 SUID 是 4 分,SGID 2 分,總共為 6 分,因此可用 +6000 來處理這個權限!至於 find 后面可以接多個目錄來進行搜尋!另外, find 本來就會搜尋次目錄,這個特色也要特別注意喔!最后,我們再來看一下 find 還有什么特殊功能吧!
| 選項與參數: 4. 額外可進行的動作:-exec command :command 為其他命令,-exec 后面可再接額外的命令來處理搜尋到的結果。-print :將結果列印到螢幕上,這個動作是默認動作!范例八:將上個范例找到的文件使用 ls -l 列出來~ [root@www ~]# find / -perm +7000 -exec ls -l {} \; # 注意到,那個 -exec 后面的 ls -l 就是額外的命令,命令不支持命令別名, # 所以僅能使用 ls -l 不可以使用 ll 喔!注意注意!范例九:找出系統中,大於 1MB 的文件 [root@www ~]# find / -size +1000k # 雖然在 man page 提到可以使用 M 與 G 分別代表 MB 與 GB, # 不過,俺卻試不出來這個功能~所以,目前應該是僅支持到 c 與 k 吧! |
find 的特殊功能就是能夠進行額外的動作(action)。我們將范例八的例子以圖解來說明如下:
圖5.2.2、find 相關的額外動作
該范例中特殊的地方有 {} 以及 \; 還有 -exec 這個關鍵字,這些東西的意義為:
- {} 代表的是『由 find 找到的內容』,如上圖所示,find 的結果會被放置到 {} 位置中;
- -exec 一直到 \; 是關鍵字,代表 find 額外動作的開始 (-exec) 到結束 (\;) ,在這中間的就是 find 命令內的額外動作。在本例中就是『 ls -l {} 』羅!
- 因為『 ; 』在 bash 環境下是有特殊意義的,因此利用反斜線來跳脫。
透過圖 5.2.2 你應該就比較容易了解 -exec 到 \; 之間的意義了吧!
如果你要找的文件是具有特殊屬性的,例如 SUID 、文件擁有者、文件大小等等,那么利用 locate 是沒有辦法達成你的搜尋的!此時 find 就顯的很重要啦!另外,find 還可以利用萬用字節來找尋檔名呢!舉例來說,你想要找出 /etc 底下檔名包含 httpd 的文件,那么你就可以這樣做:
| [root@www ~]# find /etc -name '*httpd*' |
不但可以指定搜尋的目錄(連同次目錄),并且可以利用額外的選項與參數來找到最正確的檔名!真是好好用!不過由於 find 在尋找數據的時后相當的操硬盤!所以沒事情不要使用 find 啦!有更棒的命令可以取代呦!那就是上面提到的whereis 與locate 羅!
極重要!權限與命令間的關系:
我們知道權限對於使用者帳號來說是非常重要的,因為他可以限制使用者能不能讀取/創建/刪除/修改文件或目錄!在這一章我們介紹了很多文件系統的管理命令,第六章則介紹了很多文件權限的意義。在這個小節當中,我們就將這兩者結合起來,說明一下什么命令在什么樣的權限下才能夠運行吧!^_^
一、讓使用者能進入某目錄成為『可工作目錄』的基本權限為何:
- 可使用的命令:例如 cd 等變換工作目錄的命令;
- 目錄所需權限:使用者對這個目錄至少需要具有 x 的權限
- 額外需求:如果使用者想要在這個目錄內利用 ls 查閱檔名,則使用者對此目錄還需要 r 的權限。
二、使用者在某個目錄內讀取一個文件的基本權限為何?
- 可使用的命令:例如本章談到的 cat, more, less等等
- 目錄所需權限:使用者對這個目錄至少需要具有 x 權限;
- 文件所需權限:使用者對文件至少需要具有 r 的權限才行!
三、讓使用者可以修改一個文件的基本權限為何?
- 可使用的命令:例如 nano 或未來要介紹的 vi 編輯器等;
- 目錄所需權限:使用者在該文件所在的目錄至少要有 x 權限;
- 文件所需權限:使用者對該文件至少要有 r, w 權限
四、讓一個使用者可以創建一個文件的基本權限為何?
- 目錄所需權限:使用者在該目錄要具有 w,x 的權限,重點在 w 啦!
五、讓使用者進入某目錄并運行該目錄下的某個命令之基本權限為何?
- 目錄所需權限:使用者在該目錄至少要有 x 的權限;
- 文件所需權限:使用者在該文件至少需要有 x 的權限
例題: 讓一個使用者 vbird 能夠進行『cp /dir1/file1 /dir2』的命令時,請說明 dir1, file1, dir2 的最小所需權限為何? 答: 運行 cp 時, vbird 要『能夠讀取來源檔,并且寫入目標檔!』所以應參考上述第二點與第四點的說明!因此各文件/目錄的最小權限應該是:
|
| 例題: 有一個文件全名為 /home/student/www/index.html ,各相關文件/目錄的權限如下: drwxr-xr-x 23 root root 4096 Sep 22 12:09 /
drwxr-xr-x 6 root root 4096 Sep 29 02:21 /home
drwx------ 6 student student 4096 Sep 29 02:23 /home/student
drwxr-xr-x 6 student student 4096 Sep 29 02:24 /home/student/www
-rwxr--r-- 6 student student 369 Sep 29 02:27 /home/student/www/index.html 請問 vbird 這個帳號(不屬於student群組)能否讀取 index.html 這個文件呢? 答: 雖然 www 與 index.html 是可以讓 vbird 讀取的權限,但是因為目錄結構是由根目錄一層一層讀取的,因此 vbird 可進入 /home 但是卻不可進入 /home/student/ ,既然連進入 /home/student 都不許了,當然就讀不到 index.html 了!所以答案是『vbird不會讀取到 index.html 的內容』喔! 那要如何修改權限呢?其實只要將 /home/student 的權限修改為最小 711 ,或者直接給予 755 就可以羅!這可是很重要的概念喔! |
重點回顧
- 絕對路徑:『一定由根目錄 / 寫起』;相對路徑:『不是由 / 寫起』
- 特殊目錄有:., .., -, ~, ~account需要注意;
- 與目錄相關的命令有:cd, mkdir, rmdir, pwd 等重要命令;
- rmdir 僅能刪除空目錄,要刪除非空目錄需使用『 rm -r 』命令;
- 使用者能使用的命令是依據 PATH 變量所規定的目錄去搜尋的;
- 不同的身份(root 與一般用戶)系統默認的 PATH 并不相同。差異較大的地方在於 /sbin, /usr/sbin ;
- ls 可以檢視文件的屬性,尤其 -d, -a, -l 等選項特別重要!
- 文件的復制、刪除、移動可以分別使用:cp, rm , mv等命令來操作;
- 檢查文件的內容(讀檔)可使用的命令包括有:cat, tac, nl, more, less, head, tail, od 等
- cat -n 與 nl 均可顯示行號,但默認的情況下,空白行會不會編號并不相同;
- touch 的目的在修改文件的時間參數,但亦可用來創建空文件;
- 一個文件記錄的時間參數有三種,分別是 access time(atime), status time (ctime), modification time(mtime),ls 默認顯示的是 mtime。
- 除了傳統的rwx權限之外,在Ext2/Ext3文件系統中,還可以使用chattr與lsattr配置及觀察隱藏屬性。常見的包括只能新增數據的 +a 與完全不能更動文件的 +i 屬性。
- 新建文件/目錄時,新文件的默認權限使用 umask 來規范。默認目錄完全權限為drwxrwxrwx,文件則為-rw-rw-rw-。
- 文件具有SUID的特殊權限時,代表當使用者運行此一binary程序時,在運行過程中使用者會暫時具有程序擁有者的權限
- 目錄具有SGID的特殊權限時,代表使用者在這個目錄底下新建的文件之群組都會與該目錄的群組名稱相同。
- 目錄具有SBIT的特殊權限時,代表在該目錄下使用者創建的文件只有自己與root能夠刪除!
- 觀察文件的類型可以使用 file 命令來觀察;
- 搜尋命令的完整檔名可用 which 或 type ,這兩個命令都是透過 PATH 變量來搜尋檔名;
- 搜尋文件的完整檔名可以使用 whereis 或 locate 到數據庫文件去搜尋,而不實際搜尋文件系統;
- 利用 find 可以加入許多選項來直接查詢文件系統,以獲得自己想要知道的檔名。
本章習題:
( 要看答案請將鼠標移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )
情境模擬題一:假設系統中有兩個帳號,分別是 alex 與 arod ,這兩個人除了自己群組之外還共同支持一個名為 project 的群組。假設這兩個用戶需要共同擁有 /srv/ahome/ 目錄的開發權,且該目錄不許其他人進入查閱。請問該目錄的權限配置應為何?請先以傳統權限說明,再以 SGID 的功能解析。
- 目標:了解到為何專案開發時,目錄最好需要配置 SGID 的權限!
- 前提:多個帳號支持同一群組,且共同擁有目錄的使用權!
- 需求:需要使用 root 的身份來進行 chmod, chgrp 等幫用戶配置好他們的開發環境才行!這也是管理員的重要任務之一!
| [root@www ~]# groupadd project <==添加新的群組 [root@www ~]# useradd -G project alex <==創建 alex 帳號,且支持 project [root@www ~]# useradd -G project arod <==創建 arod 帳號,且支持 project [root@www ~]# id alex <==查閱 alex 帳號的屬性 uid=501(alex) gid=502(alex) groups=502(alex),501(project) <==確實有支持! [root@www ~]# id arod uid=502(arod) gid=503(arod) groups=503(arod),501(project) |
| [root@www ~]# mkdir /srv/ahome [root@www ~]# ll -d /srv/ahome drwxr-xr-x 2 root root 4096 Sep 29 22:36 /srv/ahome |
| [root@www ~]# chgrp project /srv/ahome [root@www ~]# chmod 770 /srv/ahome [root@www ~]# ll -d /srv/ahome drwxrwx--- 2 root project 4096 Sep 29 22:36 /srv/ahome # 從上面的權限結果來看,由於 alex/arod 均支持 project,因此似乎沒問題了! |
| [root@www ~]# su - alex <==先切換身份成為 alex 來處理 [alex@www ~]$ cd /srv/ahome <==切換到群組的工作目錄去 [alex@www ahome]$ touch abcd <==創建一個空的文件出來! [alex@www ahome]$ exit <==離開 alex 的身份[root@www ~]# su - arod [arod@www ~]$ cd /srv/ahome [arod@www ahome]$ ll abcd -rw-rw-r-- 1 alex alex 0 Sep 29 22:46 abcd # 仔細看一下上面的文件,由於群組是 alex ,arod并不支持! # 因此對於 abcd 這個文件來說, arod 應該只是其他人,只有 r 的權限而已啊! [arod@www ahome]$ exit |
| [root@www ~]# chmod 2770 /srv/ahome [root@www ~]# ll -d /srv/ahome drwxrws--- 2 root project 4096 Sep 29 22:46 /srv/ahome測試:使用 alex 去創建一個文件,并且查閱文件權限看看: [root@www ~]# su - alex [alex@www ~]$ cd /srv/ahome [alex@www ahome]$ touch 1234 [alex@www ahome]$ ll 1234 -rw-rw-r-- 1 alex project 0 Sep 29 22:53 1234 # 沒錯!這才是我們要的樣子!現在 alex, arod 創建的新文件所屬群組都是 project, # 由於兩人均屬於此群組,加上 umask 都是 002,這樣兩人才可以互相修改對方的文件! |
簡答題部分:
- 什么是絕對路徑與相對路徑 絕對路徑的寫法為由 / 開始寫,至於相對路徑則不由 / 開始寫!此外,相對路徑為相對於目前工作目錄的路徑!
- 如何更改一個目錄的名稱?例如由 /home/test 變為 /home/test2 mv /home/test /home/test2
- PATH 這個環境變量的意義? 這個是用來指定運行檔運行的時候,命令搜尋的目錄路徑。
- umask 有什么用處與優點? umask 可以拿掉一些權限,因此,適當的定義 umask 有助於系統的安全,因為他可以用來創建默認的目錄或文件的權限。
- 當一個使用者的 umask 分別為 033 與 044 他所創建的文件與目錄的權限為何? 在 umask 為 033 時,則默認是拿掉 group 與 other 的 w(2)x(1) 權限,因此權限就成為『文件 -rw-r--r-- , 目錄 drwxr--r-- 』而當umask 044 時,則拿掉 r 的屬性,因此就成為『文件 -rw--w--w-,目錄 drwx-wx-wx』
- 什么是 SUID ? 當一個命令具有 SUID 的功能時,則:
- SUID 權限僅對二進位程序(binary program)有效;
- 運行者對於該程序需要具有 x 的可運行權限;
- 本權限僅在運行該程序的過程中有效 (run-time);
- 運行者將具有該程序擁有者 (owner) 的權限。
- 當我要查詢 /usr/bin/passwd 這個文件的一些屬性時(1)傳統權限;(2)文件類型與(3)文件的隱藏屬性,可以使用什么命令來查詢? ls -al
file
lsattr - 嘗試用 find 找出目前 linux 系統中,所有具有 SUID 的文件有哪些? find / -perm +4000 -print
- 找出 /etc 底下,文件大小介於 50K 到 60K 之間的文件,并且將權限完整的列出 (ls -l): find /etc -size +50k -a -size -60k -exec ls -l {} \;
注意到 -a ,那個 -a 是 and 的意思,為符合兩者才算成功 - 找出 /etc 底下,文件容量大於 50K 且文件所屬人不是 root 的檔名,且將權限完整的列出 (ls -l); find /etc -size +50k -a ! -user root -exec ls -ld {} \;
find /etc -size +50k -a ! -user root -type f -exec ls -l {} \;
上面兩式均可!注意到 ! ,那個 ! 代表的是反向選擇,亦即『不是后面的項目』之意! - 找出 /etc 底下,容量大於 1500K 以及容量等於 0 的文件: find /etc -size +1500k -o -size 0
相對於 -a ,那個 -o 就是或 (or) 的意思羅!
參考數據與延伸閱讀
- 小洲大大回答 SUID/SGID 的一篇討論:
http://phorum.vbird.org/viewtopic.php?t=20256
2002/06/26:第一次完成2003/02/06:重新編排與加入 FAQ
2003/02/07:加入 basename 與 dirname 的說明
2004/03/15:將連結檔的內容移動至下一章節:Linux 磁碟與硬件管理
2005/07/19:將舊的文章移動到 這里 了。
2005/07/20:呼呼!好不容易啊~在被臺風尾掃到的七月份,終於寫完這個咚咚~
2005/07/21:在 find 部分,多添加了范例九,以及關於利用文件大小 (size) 搜尋的功能。
2005/07/25:在 SUID/SGID/SBIT 部分,依據 netman 與 小州 兄的建議,修改了部分的敘述!
2006/04/09:在 rmdir 的范例內,少了一個 -p 的參數!
2006/06/15:經由討論局域網友 dm421 的通知,發現 chattr 的部分關於 d 寫錯了,已訂正。
2006/08/22:添加 rm 的一些簡單的說明!尤其是『 rm ./-aaa- 』的刪除方法!
2008/09/23:將針對FC4版寫的數據移到此處
2008/09/29:加入權限與命令的關系一節,并新增情境模擬題目喔!大家幫忙除錯一下!
2009/08/18:加入符號法的方式來處理 SUID/SGID/SBIT 羅!
2009/08/26:感謝網友告知習題部分,找出 /etc 底下容量大於 50k 的那題,應使用 -type f 或 ls -ld 來避免目錄內重復顯示!
出處:http://vbird.dic.ksu.edu.tw/linux_basic/0220filemanager.php
總結
以上是生活随笔為你收集整理的鸟哥的Linux私房菜(基础篇)- 第七章、Linux 文件与目录管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鸟哥的Linux私房菜(基础篇)- 第六
- 下一篇: 鸟哥的Linux私房菜(基础篇)- 第八