Linux學習:Linux 檔案與目錄管理
引用:《鳥哥的Linux私房菜基礎篇第三版》
在前一章我們認識了Linux系統下的檔案許可權概念以及目錄的配置說明。 在這個章節當中,我們就直接來進一步的操作與管理檔案及目錄吧!包括在不同的目錄間變換、 建立與刪除目錄、建立與刪除檔案,還有尋找檔案、檢視檔案內容等等,都會在這個章節作個簡單的介紹啊!
目錄與路徑
由前一章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,)
目錄的相關操作
我們之前稍微提到變換目錄的指令是cd,還有哪些可以進行目錄操作的指令呢? 例如建立目錄啊、刪除目錄之類的~還有,得要先知道的,就是有哪些比較特殊的目錄呢? 舉例來說,下面這些就是比較特殊的目錄,得要用力的記下來才行:
. 代表此層目錄 .. 代表上一層目錄 - 代表前一個工作目錄 ~ 代表『目前使用者身份』所在的家目錄 ~account 代表 account 這個使用者的家目錄(account是個賬號名稱) |
需要特別注意的是:在所有目錄下面都會存在的兩個目錄,分別是『.』與『..』 分別代表此層與上層目錄的意思。那麼來思考一下下面這個例題:
例題: 請問在Linux下面,根目錄下有沒有上層目錄(..)存在? 答: 若使用『 ls -al / 』去查詢,可以看到根目錄下確實存在 . 與 .. 兩個目錄,再仔細的檢視, 可發現這兩個目錄的屬性與許可權完全一致,這代表根目錄的上一層(..)與根目錄自己(.)是同一個目錄。 |
下面我們就來談一談幾個常見的處理目錄的指令吧:
- cd:變換目錄
- pwd:顯示當前目錄
- mkdir:建立一個新的目錄
- rmdir:刪除一個空的目錄
- cd (change directory, 變換目錄)
我們知道dmtsai這個使用者的家目錄是/home/dmtsai/,而root家目錄則是/root/,假設我以root身份在 Linux系統中,那麼簡單的說明一下這幾個特殊的目錄的意義是:
[[email protected] ~]$ su - # 先切換身份成為 root 看看! [[email protected] ~]# cd [相對路徑或絕對路徑] # 最重要的就是目錄的絕對路徑與相對路徑,還有一些特殊目錄的符號囉! [[email protected] ~]# cd ~dmtsai # 代表去到 dmtsai 這個使用者的家目錄,亦即 /home/dmtsai [[email protected] dmtsai]# cd ~ # 表示回到自己的家目錄,亦即是 /root 這個目錄 [[email protected] ~]# cd # 沒有加上任何路徑,也還是代表回到自己家目錄的意思喔! [[email protected] ~]# cd .. # 表示去到目前的上層目錄,亦即是 /root 的上層目錄的意思; [[email protected] /]# cd - # 表示回到剛剛的那個目錄,也就是 /root 囉~ [[email protected] ~]# cd /var/spool/mail # 這個就是絕對路徑的寫法!直接指定要去的完整路徑名稱! [[email protected] mail]# cd ../postfix # 這個是相對路徑的寫法,我們由/var/spool/mail 去到/var/spool/postfix 就這樣寫! |
cd是Change Directory的縮寫,這是用來變換工作目錄的指令。注意,目錄名稱與cd指令之間存在一個空格。 一登入Linux系統後,每個賬號都會在自己賬號的家目錄中。那回到上一層目錄可以用『 cd .. 』。 利用相對路徑的寫法必須要確認你目前的路徑才能正確的去到想要去的目錄。例如上表當中最後一個例子, 你必須要確認你是在/var/spool/mail當中,並且知道在/var/spool當中有個 postfix 的目錄才行啊~ 這樣才能使用cd ../postfix 去到正確的目錄說,否則就要直接輸入cd /var/spool/postfix 囉~
其實,我們的提示字元,亦即那個 [[email protected] ~]# 當中,就已經有指出當前目錄了, 剛登入時會到自己的家目錄,而家目錄還有一個程式碼,那就是『 ~ 』符號! 例如上面的例子可以發現,使用『 cd ~ 』可以回到個人的家目錄裡頭去呢! 另外,針對 cd 的使用方法,如果僅輸入 cd 時,代表的就是『 cd ~ 』的意思喔~ 亦即是會回到自己的家目錄啦!而那個『 cd - 』比較難以理解,請自行多做幾次練習,就會比較明白了。
Tips
還是要一再地提醒,我們的 Linux 的預設命令列模式 (bash shell) 具有檔案補齊功能, 你要常常利用 [tab] 按鍵來達成你的目錄完整性啊!這可是個好習慣啊~可以避免你按錯鍵盤輸入錯字說~ ^_^
- pwd (顯示目前所在的目錄)
[[email protected] ~]# pwd [-P] 選項與引數: -P :顯示出確實的路徑,而非使用連結 (link) 路徑。 範例:單純顯示出目前的工作目錄: [[email protected] ~]# pwd /root <== 顯示出目錄啦~ 範例:顯示出實際的工作目錄,而非連結檔案本身的目錄名而已 [[email protected] ~]# cd /var/mail <==注意,/var/mail是一個連結檔案 [[email protected] mail]# pwd /var/mail <==列出目前的工作目錄 [[email protected] mail]# pwd -P /var/spool/mail <==怎麼回事?有沒有加 -P 差很多~ [[email protected] mail]# ls -ld /var/mail lrwxrwxrwx. 1 root root 10 May 4 17:51 /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 7.x的話,剛剛好/var/mail是/var/spool/mail的連結檔案, 所以,通過到/var/mail下達pwd -P就能夠知道這個選項的意義囉~ ^_^
- mkdir (建立新目錄)
[[email protected] ~]# mkdir [-mp] 目錄名稱 選項與引數: -m :配置檔案的許可權喔!直接設定,不需要看預設許可權 (umask) 的臉色~ -p :幫助你直接將所需要的目錄(包含上層目錄)遞迴建立起來! 範例:請到/tmp下面嘗試建立數個新目錄看看: [[email protected] ~]# cd /tmp [[email protected] tmp]# mkdir test <==建立一名為 test 的新目錄 [[email protected] tmp]# mkdir test1/test2/test3/test4 mkdir: cannot create directory ‘test1/test2/test3/test4’: No such file or directory # 話說,系統告訴我們,沒可能建立這個目錄啊!就是沒有目錄才要建立的!見鬼嘛? [[email protected] tmp]# mkdir -p test1/test2/test3/test4 # 原來是要建 test4 上層沒先建 test3 之故!加了這個 -p 的選項,可以自行幫你建立多層目錄! 範例:建立許可權為rwx--x--x的目錄 [[email protected] tmp]# mkdir -m 711 test2 [[email protected] tmp]# ls -ld test* drwxr-xr-x. 2 root root 6 Jun 4 19:03 test drwxr-xr-x. 3 root root 18 Jun 4 19:04 test1 drwx--x--x. 2 root root 6 Jun 4 19:05 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 (刪除『空』的目錄)
[[email protected] ~]# rmdir [-p] 目錄名稱 選項與引數: -p :連同『上層』『空的』目錄也一起刪除 範例:將於mkdir範例中建立的目錄(/tmp下面)刪除掉! [[email protected] tmp]# ls -ld test* <==看看有多少目錄存在? drwxr-xr-x. 2 root root 6 Jun 4 19:03 test drwxr-xr-x. 3 root root 18 Jun 4 19:04 test1 drwx--x--x. 2 root root 6 Jun 4 19:05 test2 [[email protected] tmp]# rmdir test <==可直接刪除掉,沒問題 [[email protected] tmp]# rmdir test1 <==因為尚有內容,所以無法刪除! rmdir: failed to remove ‘test1’: Directory not empty [[email protected] tmp]# rmdir -p test1/test2/test3/test4 [[email protected] tmp]# ls -ld test* <==您看看,下面的輸出中test與test1不見了! drwx--x--x. 2 root root 6 Jun 4 19:05 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的身份列出搜尋的路徑為何? [[email protected] ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin 範例:用dmtsai的身份列出搜尋的路徑為何? [[email protected] ~]# exit # 由之前的 su - 離開,變回原本的賬號!或再取得一個終端機皆可! [[email protected] ~]$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin # 記不記得我們前一章說過,目前 /bin 是連結到 /usr/bin 當中的喔! |
PATH(一定是大寫)這個變數的內容是由一堆目錄所組成的,每個目錄中間用冒號(:)來隔開, 每個目錄是有『順序』之分的。仔細看一下上面的輸出,你可以發現到無論是root還是dmtsai都有 /bin 或 /usr/bin 這個目錄在PATH變數內,所以當然就能夠在任何地方執行ls來找到/bin/ls執行檔案囉!因為 /bin 在 CentOS 7 當中,就是連結到 /usr/bin 去的! 所以這兩個目錄內容會一模一樣!
我們用幾個範例來讓你瞭解一下,為什麼PATH是那麼重要的專案!
例題: 假設你是root,如果你將ls由/bin/ls移動成為/root/ls(可用『mv /bin/ls /root』指令完成),然後你自己本身也在/root目錄下, 請問(1)你能不能直接輸入ls來執行?(2)若不能,你該如何執行ls這個指令?(3)若要直接輸入ls即可執行,又該如何進行? 答: 由於這個例題的重點是將某個執行檔案移動到非正規目錄去,所以我們先要進行下面的動作才行:(務必先使用 su - 切換成為root的身份)
(1)接下來不論你在那個目錄下面輸入任何與ls相關的指令,都沒有辦法順利的執行ls了! 也就是說,你不能直接輸入ls來執行,因為/root這個目錄並不在PATH指定的目錄中, 所以,即使你在/root目錄下,也不能夠搜尋到ls這個指令! (2)因為這個ls確實存在於/root下面,並不是被刪除了!所以我們可以通過使用絕對路徑或者是相對路徑直接指定這個執行檔案檔名, 下面的兩個方法都能夠執行ls這個指令:
(3)如果想要讓root在任何目錄均可執行/root下面的ls,那麼就將/root加入PATH當中即可。 加入的方法很簡單,就像下面這樣:
上面這個作法就能夠將/root加入到執行檔案搜尋路徑PATH中了!不相信的話請您自行使用『echo $PATH』去檢視吧! 另外,除了 $PATH 之外,如果想要更明確的定義出變數的名稱,可以使用大括號 ${PATH} 來處理變數的呼叫喔! 如果確定這個例題進行沒有問題了,請將ls搬回/bin下面,不然系統會掛點的!
某些情況下,即使你已經將 ls 搬回 /bin 了,不過系統還是會告知你無法處理 /root/ls 喔!很可能是因為指令引數被快取的關係。 不要緊張,只要登出 (exit) 再登入 (su -) 就可以繼續快樂的使用 ls 了! |
例題: 如果我有兩個ls指令在不同的目錄中,例如/usr/local/bin/ls與/bin/ls那麼當我下達 ls 的時候,哪個ls會被執行? 答: 那還用說,就找出 ${PATH} 裡面哪個目錄先被查詢,則那個目錄下的指令就會被先執行了!所以用 dmtsai 賬號為例,他最先搜尋的是 /usr/local/bin, 所以 /usr/local/bin/ls 會先被執行喔! |
例題: 為什麼 ${PATH} 搜尋的目錄不加入本目錄(.)?加入本目錄的搜尋不是也不錯? 答: 如果在PATH中加入本目錄(.)後,確實我們就能夠在指令所在目錄進行指令的執行了。 但是由於你的工作目錄並非固定(常常會使用cd來切換到不同的目錄), 因此能夠執行的指令會有變動(因為每個目錄下面的可執行檔案都不相同嘛!),這對使用者來說並非好事。 另外,如果有個壞心使用者在/tmp下面做了一個指令,因為/tmp是大家都能夠寫入的環境,所以他當然可以這樣做。 假設該指令可能會竊取使用者的一些資料,如果你使用root的身份來執行這個指令,那不是很糟糕? 如果這個指令的名稱又是經常會被用到的ls時,那『中標』的機率就更高了! 所以,為了安全起見,不建議將『.』加入PATH的搜尋目錄中。 |
而由上面的幾個例題我們也可以知道幾件事情:
- 不同身份使用者預設的PATH不同,預設能夠隨意執行的指令也不同(如root與dmtsai);
- PATH是可以修改的;
- 使用絕對路徑或相對路徑直接指定某個指令的檔名來執行,會比搜尋PATH來的正確;
- 指令應該要放置到正確的目錄下,執行才會比較方便;
- 本目錄(.)最好不要放到PATH當中。
對於PATH更詳細的『變數』說明,我們會在bash shell中詳細說明的!
檔案與目錄管理
談了談目錄與路徑之後,再來討論一下關於檔案的一些基本管理吧!檔案與目錄的管理上,不外乎『顯示屬性』、 『拷貝』、『刪除檔案』及『移動檔案或目錄』等等,由於檔案與目錄的管理在 Linux 當中是很重要的, 尤其是每個人自己家目錄的資料也都需要注意管理!所以我們來談一談有關檔案與目錄的一些基礎管理部分吧!
檔案與目錄的檢視: ls
[[email protected] ~]# ls [-aAdfFhilnrRSt] 檔名或目錄名稱.. [[email protected] ~]# ls [--color={never,auto,always}] 檔名或目錄名稱.. [[email protected] ~]# 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 選項等等。 下面則是一些常用的範例,實際試做看看:
範例一:將家目錄下的所有檔案列出來(含屬性與隱藏檔案) [[email protected] ~]# ls -al ~ total 56 dr-xr-x---. 5 root root 4096 Jun 4 19:49 . dr-xr-xr-x. 17 root root 4096 May 4 17:56 .. -rw-------. 1 root root 1816 May 4 17:57 anaconda-ks.cfg -rw-------. 1 root root 6798 Jun 4 19:53 .bash_history -rw-r--r--. 1 root root 18 Dec 29 2013 .bash_logout -rw-r--r--. 1 root root 176 Dec 29 2013 .bash_profile -rw-rw-rw-. 1 root root 176 Dec 29 2013 .bashrc -rw-r--r--. 1 root root 176 Jun 3 00:04 .bashrc_test drwx------. 4 root root 29 May 6 00:14 .cache drwxr-xr-x. 3 root root 17 May 6 00:14 .config # 這個時候你會看到以 . 為開頭的幾個檔案,以及目錄檔案 (.) (..) .config 等等, # 不過,目錄檔案檔名都是以深藍色顯示,有點不容易看清楚就是了。 範例二:承上題,不顯示顏色,但在檔名末顯示出該檔名代表的型別(type) [[email protected] ~]# ls -alF --color=never ~ total 56 dr-xr-x---. 5 root root 4096 Jun 4 19:49 ./ dr-xr-xr-x. 17 root root 4096 May 4 17:56 ../ -rw-------. 1 root root 1816 May 4 17:57 anaconda-ks.cfg -rw-------. 1 root root 6798 Jun 4 19:53 .bash_history -rw-r--r--. 1 root root 18 Dec 29 2013 .bash_logout -rw-r--r--. 1 root root 176 Dec 29 2013 .bash_profile -rw-rw-rw-. 1 root root 176 Dec 29 2013 .bashrc -rw-r--r--. 1 root root 176 Jun 3 00:04 .bashrc_test drwx------. 4 root root 29 May 6 00:14 .cache/ drwxr-xr-x. 3 root root 17 May 6 00:14 .config/ # 注意看到顯示結果的第一行,嘿嘿~知道為何我們會下達類似 ./command # 之類的指令了吧?因為 ./ 代表的是『目前目錄下』的意思啊!至於什麼是 FIFO/Socket ? # 請參考前一章節的介紹啊!另外,那個.bashrc 時間僅寫2013,能否知道詳細時間? 範例三:完整的呈現檔案的修改時間 (modification time) [[email protected] ~]# ls -al --full-time ~ total 56 dr-xr-x---. 5 root root 4096 2015-06-04 19:49:54.520684829 +0800 . dr-xr-xr-x. 17 root root 4096 2015-05-04 17:56:38.888000000 +0800 .. -rw-------. 1 root root 1816 2015-05-04 17:57:02.326000000 +0800 anaconda-ks.cfg -rw-------. 1 root root 6798 2015-06-04 19:53:41.451684829 +0800 .bash_history -rw-r--r--. 1 root root 18 2013-12-29 10:26:31.000000000 +0800 .bash_logout -rw-r--r--. 1 root root 176 2013-12-29 10:26:31.000000000 +0800 .bash_profile -rw-rw-rw-. 1 root root 176 2013-12-29 10:26:31.000000000 +0800 .bashrc -rw-r--r--. 1 root root 176 2015-06-03 00:04:16.916684829 +0800 .bashrc_test drwx------. 4 root root 29 2015-05-06 00:14:56.960764950 +0800 .cache drwxr-xr-x. 3 root root 17 2015-05-06 00:14:56.975764950 +0800 .config # 請仔細看,上面的『時間』欄位變了喔!變成較為完整的格式。 # 一般來說, 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 (複製檔案或目錄)
[[email protected] ~]# cp [-adfilprsu] 來原始檔(source) 目標檔案(destination) [[email protected] ~]# cp [options] source1 source2 source3 .... directory 選項與引數: -a :相當於 -dr --preserve=all 的意思,至於 dr 請參考下列說明;(常用) -d :若來原始檔為連結檔案的屬性(link file),則複製連結檔案屬性而非檔案本身; -f :為強制(force)的意思,若目標檔案已經存在且無法開啟,則移除後再嘗試一次; -i :若目標檔案(destination)已經存在時,在覆蓋時會先詢問動作的進行(常用) -l :進行硬式連結(hard link)的連結檔案建立,而非複製檔案本身; -p :連同檔案的屬性(許可權、使用者、時間)一起復制過去,而非使用預設屬性(備份常用); -r :遞迴持續複製,用於目錄的複製行為;(常用) -s :複製成為符號連結檔案 (symbolic link),亦即『快捷方式』檔案; -u :destination 比 source 舊才更新 destination,或 destination 不存在的情況下才複製。 --preserve=all :除了 -p 的許可權相關引數外,還加入 SELinux 的屬性, links, xattr 等也複製了。 最後需要注意的,如果原始檔有兩個以上,則最後一個目的檔案一定要是『目錄』才行! |
複製(cp)這個指令是非常重要的,不同身份者執行這個指令會有不同的結果產生,尤其是那個-a, -p的選項, 對於不同身份來說,差異則非常的大!下面的練習中,有的身份為root有的身份為一般賬號 (在我這裡用 dmtsai 這個賬號), 練習時請特別注意身份的差別喔!好!開始來做複製的練習與觀察:
範例一:用root身份,將家目錄下的 .bashrc 複製到 /tmp 下,並更名為 bashrc [[email protected] ~]# cp ~/.bashrc /tmp/bashrc [[email protected] ~]# cp -i ~/.bashrc /tmp/bashrc cp: overwrite `/tmp/bashrc'? n <==n不覆蓋,y為覆蓋 # 重複作兩次動作,由於 /tmp 下面已經存在 bashrc 了,加上 -i 選項後, # 則在覆蓋前會詢問使用者是否確定!可以按下 n 或者 y 來二次確認呢! 範例二:變換目錄到/tmp,並將/var/log/wtmp複製到/tmp且觀察屬性: [[email protected] ~]# cd /tmp [[email protected] tmp]# cp /var/log/wtmp . <==想要複製到當前目錄,最後的 . 不要忘 [[email protected] tmp]# ls -l /var/log/wtmp wtmp -rw-rw-r--. 1 root utmp 28416 Jun 11 18:56 /var/log/wtmp -rw-r--r--. 1 root root 28416 Jun 11 19:01 wtmp # 注意上面的特殊字型,在不加任何選項的情況下,檔案的某些屬性/許可權會改變; # 這是個很重要的特性!要注意喔!還有,連檔案建立的時間也不一樣了! # 那如果你想要將檔案的所有特性都一起復制過來該怎辦?可以加上 -a 喔!如下所示: [[email protected] tmp]# cp -a /var/log/wtmp wtmp_2 [[email protected] tmp]# ls -l /var/log/wtmp wtmp_2 -rw-rw-r--. 1 root utmp 28416 Jun 11 18:56 /var/log/wtmp -rw-rw-r--. 1 root utmp 28416 Jun 11 18:56 wtmp_2 # 瞭了吧!整個資料特性完全一模一樣!真是不賴~這就是 -a 的特性! |
這個 cp 的功能很多,由於我們常常會進行一些資料的複製,所以也會常常用到這個指令的。 一般來說,我們如果去複製別人的資料 (當然,該檔案你必須要有 read 的許可權才行啊! ^_^) 時, 總是希望複製到的資料最後是我們自己的,所以,在預設的條件中, cp 的原始檔與目標檔案的許可權是不同的,目標檔案的擁有者通常會是指令操作者本身。舉例來說, 上面的範例二中,由於我是 root 的身份,因此複製過來的檔案擁有者與群組就改變成為 root 所有了! 這樣說,可以明白嗎?^_^
由於具有這個特性,因此當我們在進行備份的時候,某些需要特別注意的特殊許可權檔案, 例如密碼檔案 (/etc/shadow) 以及一些配置檔案,就不能直接以 cp 來複制,而必須要加上 -a 或者是 -p 等等可以完整複製檔案許可權的選項才行!另外,如果你想要複製檔案給其他的使用者, 也必須要注意到檔案的許可權(包含讀、寫、執行以及檔案擁有者等等), 否則,其他人還是無法針對你給予的檔案進行修訂的動作喔!注意注意!
範例三:複製 /etc/ 這個目錄下的所有內容到 /tmp 下面 [[email protected] tmp]# cp /etc/ /tmp cp: omitting directory `/etc' <== 如果是目錄則不能直接複製,要加上 -r 的選項 [[email protected] tmp]# cp -r /etc/ /tmp # 還是要再次的強調喔! -r 是可以複製目錄,但是,檔案與目錄的許可權可能會被改變 # 所以,也可以利用『 cp -a /etc /tmp 』來下達指令喔!尤其是在備份的情況下! 範例四:將範例一複製的 bashrc 建立一個連結檔案 (symbolic link) [[email protected] tmp]# ls -l bashrc -rw-r--r--. 1 root root 176 Jun 11 19:01 bashrc <==先觀察一下檔案情況 [[email protected] tmp]# cp -s bashrc bashrc_slink [[email protected] tmp]# cp -l bashrc bashrc_hlink [[email protected] tmp]# ls -l bashrc* -rw-r--r--. 2 root root 176 Jun 11 19:01 bashrc <==與原始檔不太一樣了! -rw-r--r--. 2 root root 176 Jun 11 19:01 bashrc_hlink lrwxrwxrwx. 1 root root 6 Jun 11 19:06 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 新才複製過來 [[email protected] tmp]# cp -u ~/.bashrc /tmp/bashrc # 這個 -u 的特性,是在目標檔案與來原始檔有差異時,才會複製的。 # 所以,比較常被用於『備份』的工作當中喔! ^_^ 範例六:將範例四造成的 bashrc_slink 複製成為 bashrc_slink_1 與bashrc_slink_2 [[email protected] tmp]# cp bashrc_slink bashrc_slink_1 [[email protected] tmp]# cp -d bashrc_slink bashrc_slink_2 [[email protected] tmp]# ls -l bashrc bashrc_slink* -rw-r--r--. 2 root root 176 Jun 11 19:01 bashrc lrwxrwxrwx. 1 root root 6 Jun 11 19:06 bashrc_slink -> bashrc -rw-r--r--. 1 root root 176 Jun 11 19:09 bashrc_slink_1 <==與原始檔相同 lrwxrwxrwx. 1 root root 6 Jun 11 19:10 bashrc_slink_2 -> bashrc <==是連結檔案! # 這個例子也是很有趣喔!原本複製的是連結檔案,但是卻將連結檔案的實際檔案複製過來了 # 也就是說,如果沒有加上任何選項時,cp複製的是原始檔,而非連結檔案的屬性! # 若要複製連結檔案的屬性,就得要使用 -d 的選項了!如 bashrc_slink_2 所示。 範例七:將家目錄的 .bashrc 及 .bash_history 複製到 /tmp 下面 [[email protected] tmp]# cp ~/.bashrc ~/.bash_history /tmp # 可以將多個數據一次複製到同一個目錄去!最後面一定是目錄! |
例題: 你能否使用 dmtsai 的身份,完整的複製/var/log/wtmp檔案到/tmp下面,並更名為dmtsai_wtmp呢? 答: 實際做看看的結果如下:
由於 dmtsai 的身份並不能隨意修改檔案的擁有者與群組,因此雖然能夠複製wtmp的相關許可權與時間等屬性, 但是與擁有者、群組相關的,原本 dmtsai 身份無法進行的動作,即使加上 -a 選項,也是無法達成完整複製許可權的! |
總之,由於 cp 有種種的檔案屬性與許可權的特性,所以,在複製時,你必須要清楚的瞭解到:
- 是否需要完整的保留來原始檔的資訊?
- 來原始檔是否為連結檔案 (symbolic link file)?
- 原始檔是否為特殊的檔案,例如 FIFO, socket 等?
- 來原始檔是否為目錄?
- rm (移除檔案或目錄)
[[email protected] ~]# rm [-fir] 檔案或目錄 選項與引數: -f :就是 force 的意思,忽略不存在的檔案,不會出現警告資訊; -i :互動模式,在刪除前會詢問使用者是否動作 -r :遞迴刪除啊!最常用在目錄的刪除了!這是非常危險的選項!!! 範例一:將剛剛在 cp 的範例中建立的 bashrc 刪除掉! [[email protected] ~]# cd /tmp [[email protected] tmp]# rm -i bashrc rm: remove regular file `bashrc'? y # 如果加上 -i 的選項就會主動詢問喔,避免你刪除到錯誤的檔名! 範例二:通過萬用字元*的幫忙,將/tmp下面開頭為bashrc的檔名通通刪除: [[email protected] tmp]# rm -i bashrc* # 注意那個星號,代表的是 0 到無窮多個任意字元喔!很好用的東西! 範例三:將 cp 範例中所建立的 /tmp/etc/ 這個目錄刪除掉! [[email protected] tmp]# rmdir /tmp/etc rmdir: failed to remove '/tmp/etc': Directory not empty <== 刪不掉啊!因為這不是空的目錄! [[email protected] tmp]# rm -r /tmp/etc rm: descend into directory `/tmp/etc'? y rm: remove regular file `/tmp/etc/fstab'? y rm: remove regular empty file `/tmp/etc/crypttab'? ^C <== 按下 [ctrl]+c 中斷 .....(中間省略)..... # 因為身份是 root ,預設已經加入了 -i 的選項,所以你要一直按 y 才會刪除! # 如果不想要繼續按 y ,可以按下『 [ctrl]-c 』來結束 rm 的工作。 # 這是一種保護的動作,如果確定要刪除掉此目錄而不要詢問,可以這樣做: [[email protected] tmp]# \rm -r /tmp/etc # 在指令前加上反斜槓,可以忽略掉 alias 的指定選項喔!至於 alias 我們在bash再談! # 拜託!這個範例很可怕!你不要刪錯了!刪除 /etc 系統是會掛掉的! 範例四:刪除一個帶有 - 開頭的檔案 [[email protected] tmp]# touch ./-aaa- <==touch這個指令可以建立空檔案! [[email protected] tmp]# ls -l -rw-r--r--. 1 root root 0 Jun 11 19:22 -aaa- <==檔案大小為0,所以是空檔案 [[email protected] tmp]# rm -aaa- rm: invalid option -- 'a' <== 因為 "-" 是選項嘛!所以系統誤判了! Try 'rm ./-aaa-' to remove the file `-aaa-'. <== 新的 bash 有給建議的 Try 'rm --help' for more information. [[email protected] tmp]# rm ./-aaa- |
這是移除的指令(remove),要注意的是,通常在Linux系統下,為了怕檔案被 root 誤殺,所以很多 distributions 都已經預設加入 -i 這個選項了!而如果要連目錄下的東西都一起殺掉的話, 例如子目錄裡面還有子目錄時,那就要使用 -r 這個選項了!不過,使用『 rm -r 』這個指令之前,請千萬注意了,因為該目錄或檔案『肯定』會被 root 殺掉!因為系統不會再次詢問你是否要砍掉呦!所以那是個超級嚴重的指令下達呦! 得特別注意!不過,如果你確定該目錄不要了,那麼使用 rm -r 來迴圈殺掉是不錯的方式!
另外,範例四也是很有趣的例子,我們在之前就談過,檔名最好不要使用 "-" 號開頭, 因為 "-" 後面接的是選項,因此,單純的使用『 rm -aaa- 』系統的指令就會誤判啦! 那如果使用後面會談到的正規表示法時,還是會出問題的!所以,只能用避過首位字元是 "-" 的方法啦! 就是加上本目錄『 ./ 』即可!如果 man rm 的話,其實還有一種方法,那就是『 rm -- -aaa- 』也可以啊!
- mv (移動檔案與目錄,或更名)