檔案管理的方式、檔案內容的查詢,還有最重要的 vim 運作!不過,簡單簡單講講!先熟悉為主!
前一堂課讀者應該稍微接觸 Linux 檔案的管理,這一堂課我們將較深入的操作 Linux 檔案管理。 此外,本章課程亦會介紹未來將持續使用的 vim 程式編輯器,學會 vim 對於系統管理員來說,是相當重要的任務! 雖然某些時刻系統可能只會提供 vi 而已,但是,我們使用者一般操作 Linux 時,個人建議還是學會 vim 更好!
在 Linux 底下,所有的東西都以檔案來呈現,不同的檔案特性會有不同的結果。讀者可以常見的兩種檔案格式為:
為何需要目錄檔?讀者可以想像,如果僅有一個櫃子,你將所有書籍全部丟進同一個櫃子中,則未來要找資料時,會很難找尋 (因為單品太多)。 若可以有多個櫃子,將不同的資料分類放置於各別的櫃子中,未來要找某一類別的資料,只要找到該類別的櫃子,就能夠快速的找到資料 (單品較少), 這就是目錄檔案的重點。
前一堂課已經談過,目錄的建立主要使用 mkdir 這個指令,這個指令將建立一個『空目錄』。所謂的『空目錄』意指該目錄內並沒有其他檔案的存在。 至於刪除目錄則使用 rmdir 這個指令,但同理,這個指令僅能『刪除空目錄』而已。
使用 rm 可以刪除檔案,但預設 rm 僅能刪除一般檔案無法刪除目錄,除非加上某些選項才行。
當使用 ll dirname 時,預設會顯示出『該目錄下的檔名』,因為目錄的內容就是檔名資料。若讀者需要了解到目錄本身的資訊,而不是目錄的內容, 可以使用 -d 的選項,如下範例:
[student@localhost ~]$ ll /etc/cron.d total 4 -rw-r--r--. 1 root root 128 Nov 1 03:55 0hourly # 此時,你看到的上面的資料,是 /etc/cron.d 目錄內的檔名列表,並不是 cron.d 本身的狀態! [student@localhost ~]$ ll -d /etc/cron.d drwxr-xr-x. 2 root root 21 Feb 16 11:44 /etc/cron.d # 這時,才是順利的顯示 cron.d 的狀態
承上,讀者可以清楚的看到有沒有加上 -d 的選項結果差異相當大。
在 bash 的環境中,要查詢某些關鍵字的資訊時,需要透過一些終端機環境下的特殊字元的支援,此即為萬用字元。經常使用的萬用字元有:
符號 | 意義 |
* | 代表『 0 個到無窮多個』任意字元 |
? | 代表『一定有一個』任意字元 |
[ ] | 同樣代表『一定有一個在括號內』的字元(非任意字元)。例如 [abcd] 代表『一定有一個字元, 可能是 a, b, c, d 這四個任何一個』 |
[ - ] | 若有減號在中括號內時,代表『在編碼順序內的所有字元』。例如 [0-9] 代表 0 到 9 之間的所有數字,因為數字的語系編碼是連續的! |
[^ ] | 若中括號內的第一個字元為指數符號 (^) ,那表示『反向選擇』,例如 [^abc] 代表 一定有一個字元,只要是非 a, b, c 的其他字元就接受的意思。 |
若讀者想要了解 /etc 底下有多少檔名開頭為 cron 的檔案時,可以使用如下的方式查詢:
[student@localhost ~]$ ll /etc/cron* [student@localhost ~]$ ll -d /etc/cron*
如果加上 -d 的選項,則檔名會變得比較單純,但若沒有加上 -d 的選項,則 ll 會列出『許多目錄內的檔名資料』, 與預設想要了解的檔名有所差異。因此 -d 選項就顯的更為重要。
前一堂課也稍微介紹過複製,複製主要使用 cp 來處理,相關的選項請自行 man cp 來查詢。 預設 cp 僅複製檔案,並不會複製目錄,若需要複製目錄,一般建議直接加上 -r ,而如果是需要完整備份,則最好加上 -a 的選項為宜。 至於為何是 -a,也請自行 man cp 喔!
另外,除了正常的一般檔案與目錄檔案之外,系統也經常會有連結檔的情況出現,例如底下的資料:
[student@localhost ~]$ ll /etc/rc.local /etc/rc.d/rc.local -rw-r--r--. 1 root root 474 Nov 15 18:18 /etc/rc.d/rc.local lrwxrwxrwx. 1 root root 13 Nov 15 18:18 /etc/rc.local -> rc.d/rc.local
連結檔的特色是,該行開頭的 10 個字元最左邊為 l (link) ,一般檔案為減號 (-) 而目錄檔為 d (directory)。 如上表所示,其實 /etc/rc.local 與 /etc/rc.d/rc.local 是相同的資料,其中 /etc/rc.local 是連結檔,而原始檔為 /etc/rc.d/rc.local。 此時讀者需要注意,亦即當你開啟 /etc/rc.local 時,代表實際編輯 /etc/rc.d/rc.local 那個檔案的意思。
一般來說,複製目錄需要加上 -r 或 -a,兩者的差異如下:
# 先理解複製連結檔需要注意的事項: [student@localhost ~]$ cd /dev/shm [student@localhost shm]$ ll /var drwxr-xr-x. 13 root root 4096 Feb 20 00:30 log lrwxrwxrwx. 1 root root 10 May 16 2022 mail -> spool/mail drwxr-xr-x. 2 root root 6 May 16 2022 nis .... [student@localhost shm]$ cp -r /var/mail . [student@localhost shm]$ ll lrwxrwxrwx. 1 student student 10 Feb 20 10:38 mail -> spool/mail # 由於這個 /var/mail 連結到的是一個目錄檔,因此,當你複製時,若結尾沒有加上 / 的話, # 就會像這個案例一樣,你只是複製連結檔本身,而不是原本實際的資料。 [student@localhost shm]$ rm mail [student@localhost shm]$ cp -r /var/mail/ . <==結尾一定要加上斜線 / [student@localhost shm]$ ll drwxr-xr-x. 2 student student 60 Feb 20 10:41 mail <==這樣就複製過來了。 # 查看使用 -r 複製時,兩個目錄間的差異: [student@localhost shm]$ ll mail /var/mail/ mail: total 0 -rw-r-----. 1 student student 0 Feb 20 10:41 student /var/mail/: total 0 -rw-rw----. 1 student mail 0 Feb 16 11:51 student # 因為我們用一般帳號嘗試複製,所以權限不同還 OK。問題是,怎麼連檔案的時間也不同? # 測試 -a 複製時,嘗試複製權限的行為狀態: [student@localhost shm]$ cp -a /var/mail/ mail2 [student@localhost shm]$ ll mail2 -rw-rw----. 1 student student 0 Feb 16 11:51 student # 看起來時間參數就跟原本的相同了。
讀者可以發現 -a 時,連同檔案的時間也都複製過來,而不是使用目前的時間來建立新的檔案。此外,如果以 root 的身份來執行上述指令時, 則連同權限 (前面的 root 變成 student) 也會跟原始檔案相同!這就是 -r 與 -a 的差異。因此,當系統備份時,還是建議使用 -a 的。
當你使用 cp 進行複製時,先來查看一下 cp --help 的語法說明:
[student@localhost ~]$ cp --help
用法:cp [選項]... [-T] 來源 目的地
或:cp [選項]... 來源... 目錄
或:cp [選項]... -t 目錄 來源...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
......
在基本的語法當中,如果來源只有一個,那麼目的地就不限制是檔案或目錄。如果來源有多個,那麼最後的目的地就一定要是目錄。 那如果加上 -t 呢,則必需要來源與目標的順序對調...這個作法也相當有趣,我們可以查看一下底下的範例來理解『目的地』是檔案或目錄時的差異。
當複製目錄,且目標為未存在的目錄,則系統會建立一個同名的目錄名稱來存放資料。但若目標檔案已存在, 則原始目錄將會被放置到目標檔案內,因此目標目錄是否存在,會影響到複製的結果。
刪除檔案使用 rm,其中需要特別注意,不要隨便使用 rm - rf 這樣的選項,因為 -r 為刪除目錄, -f 為不詢問直接刪除, 因此若後續的檔名寫錯時,將會有相當大的影響 (一般來說,檔案刪除是無法救援回來的)。
在 windows 底下經常會有比較特別的檔名出現,最常出現者為檔名含空白字元的情況。由於指令操作行為下,空白鍵亦為特殊字元, 因此操作上需要將這些特殊字元改為一般字元後,方可進行處理。常見的處理方式有這些情況:
一般可以使用單引號或雙引號或反斜線 (\) 來處理這樣的檔名。例如建立一個名為『 class one 』的檔名時,可以這樣做:
[student@localhost ~]$ cd /dev/shm [student@localhost shm]$ mkdir "class one" [student@localhost shm]$ ll drwxr-xr-x. 2 student student 40 Feb 20 10:50 'class one'
RockyLinux 9 很特別,在有特殊檔名的狀態下,會主動的在檔名左右兩側加上單引號~不過,這只是顯示的狀態而已, 事實上,這個檔名其實是沒有單引號的喔!不要被 ll 的結果誤導了。
讀者可以發現最右邊出現了 class one 的檔名,但這個檔名要如何刪除呢?
[student@localhost shm]$ rmdir class one rmdir: failed to remove ‘class’: 沒有此一檔案或目錄 rmdir: failed to remove ‘one’: 沒有此一檔案或目錄 [student@localhost shm]$ rmdir class\ one # 其實,使用『 rmdir cla[tab] 』就可以讓 bash 自動幫你將檔名補齊喔!
如果僅單純的補上檔名,則 rmdir 會誤判有兩個名為 class 與 one 的目錄要刪除,因為找不到,所以回報錯誤。此時你可以使用成對雙引號或單引號來處理, 也可以透過反斜線將空白變成一般字元即可 (其實透過按下 [tab] 按鈕也可以找到上述的方式來刪除!)
讀者應該知道指令下達時,在指令後的選項為開頭是 + 或 - 的項目,如果檔名被要求建立成 -newdir 時,該如何處理?
[student@localhost shm]$ mkdir -newdir
mkdir: 不適用的選項 -- n
Try 'mkdir --help' for more information.
此時會回報錯誤,若嘗試使用單引號來處理時,同樣回報錯誤!使用反斜線,同樣回報錯誤。是否無法建立此類檔名呢? 其實讀者可以透過『絕對/相對路徑』的作法來處理,例如:
[student@localhost shm]$ mkdir /dev/shm/-newdir <==這是絕對路徑檔名 [student@localhost shm]$ mkdir ./-newdir2 <==這是相對路徑檔名 [student@localhost shm]$ ll -d ./*new* drwxr-xr-x. 2 student student 40 Feb 20 10:52 ./-newdir drwxr-xr-x. 2 student student 40 Feb 20 10:52 ./-newdir2
這樣就可以建立開頭為 + 或 - 的檔名。刪除同樣得要使用這樣的檔名撰寫方式來處理。
要觀察隱藏檔時,可以使用如下的方式來處理:
# 預設情境,亦即不顯示隱藏檔 [student@localhost shm]$ cd [student@localhost ~]$ ll total 8 drwxr-xr-x. 2 student student 6 Feb 17 13:49 Desktop drwxr-xr-x. 2 student student 6 Feb 17 13:49 Documents drwxr-xr-x. 2 student student 6 Feb 17 13:49 Downloads ....... # 同時顯示隱藏檔與正常檔案 [student@localhost ~]$ ll -a total 40 drwx------. 14 student student 4096 Feb 19 22:08 . drwxr-xr-x. 3 root root 21 Feb 16 11:51 .. -rw-------. 1 student student 2883 Feb 19 23:05 .bash_history -rw-r--r--. 1 student student 18 Nov 2 00:47 .bash_logout -rw-r--r--. 1 student student 141 Nov 2 00:47 .bash_profile ....... # 特殊情境,只會顯示隱藏檔 [student@localhost ~]$ ll -d .*
由於隱藏檔是檔名開頭為小數點的檔名,因此可以透過 -a 來查詢所有的檔案,或者是透過 .* 來找隱藏檔而已。 不過得要加上 -d 的選項才行,否則會連同一堆目錄內容也被抓出來,畫面就太亂了。
但如果需要觀察檔案的類型與型態,就需要使用 file 這個指令來觀察。例如分別找出 /etc/passwd 即 /usr/bin/passwd 這兩個檔案的格式為何?
[student@localhost ~]$ ll /etc/passwd /usr/bin/passwd -rw-r--r--. 1 root root 2098 Feb 16 11:51 /etc/passwd -rwsr-xr-x. 1 root root 32656 May 15 2022 /usr/bin/passwd [student@localhost ~]$ file /etc/passwd /usr/bin/passwd /etc/passwd: ASCII text /usr/bin/passwd: setuid ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3e7d2823ae1f6faa96ad82397a23238094040086, for GNU/Linux 3.2.0, stripped
讀者即可知道這兩個檔案分別是文字檔 (ASCII text) 及執行檔 (ELF 64-bit LSB...)。
若檔案建立到錯誤的位置時,可以使用 mv 來處理。同時若檔名鍵錯,也能夠使用 mv 來更名。
有時候為了測試系統,管理員可能需要建立許多的檔名來測試,此時可以透過 touch 這個指令來處理。例如到 /dev/shm 建立名為 testdir 與 testfile 兩個『目錄檔與一般檔』, 可以這樣處理。
[student@localhost ~]$ cd /dev/shm [student@localhost shm]$ mkdir testdir [student@localhost shm]$ touch testfile [student@localhost shm]$ ll -d test* drwxr-xr-x. 2 student student 40 Feb 20 11:04 testdir -rw-r--r--. 1 student student 0 Feb 20 11:04 testfile
如果需要建立較多的檔名,例如 test1, test2, test3, test4 時,可以透過大括號的方式來處理。例如在 /dev/shm 底下建立上述的四個檔案,可以這樣處理:
[student@localhost shm]$ touch test{1,2,3,4} [student@localhost shm]$ ll -d test? -rw-r--r--. 1 student student 0 Feb 20 11:05 test1 -rw-r--r--. 1 student student 0 Feb 20 11:05 test2 -rw-r--r--. 1 student student 0 Feb 20 11:05 test3 -rw-r--r--. 1 student student 0 Feb 20 11:05 test4
如果所需要的檔名或輸出資訊是有用到連續數字時,假設由 1 到 10 這組數字,雖然能使用 {1,2,3,4,5,6,7,8,9,10} 來處理,然而輸入太繁瑣。 此時可以使用 {1..10} 來取代上述的輸出。若需要輸出 01, 02 這樣的字樣 {01..10} 來處理。
很多時候管理員只是需要知道檔案內容,並沒有進行編輯。此時可以透過一些簡易的指令來查詢文件檔案的內容。
最簡單的查詢檔案內容的方式為透過 cat, head 與 tail 等指令。cat 為較常用的指令,但是 cat 會將檔案完整的重現在螢幕上, 因此若管理員想要查詢最後幾行時,以 tail 指令查詢會較佳。
上述的 cat/head/tail 需要查詢資料時,得要人工眼力查詢,因此,如果資料量比較大,而且需要查詢資訊時,可以透過 more 與 less 來處置。 more 預設會一頁一頁向後翻動,而 less 則可以向前、向後翻頁,事實上, man page 就是呼叫 less 指令的函數處理的方式。
more 軟體內常用指令:
less 軟體內常用指令:
若需要查詢資料的行號時,可以透過 cat -n 配合管線命令來處理。例如,先將 /etc/services 的輸出加上行號,然後交由 less 處理,再去搜尋 http 所在行, 要執行這個指令則為:
[student@localhost ~]$ cat -n /etc/services | less
關於管線命令的使用,後續的章節會談論更多,在此讀者僅須知道在管線 (|) 之前所輸出的資訊,會傳給管線後的指令繼續讀入處理的意思。 亦即訊息資料並不是來自檔案,而是來自於前一個檔案的輸出。
管理員總是會需要變動系統設定檔,或者是進行純文字檔的編輯,此時就需要 vi/vim 的支援。因為 vi/vim 是 Linux 很多指令預設會去呼叫的編輯程式, 因此管理員『務必』要學會這個編輯器。另外, vim 會有顏色的支援, vi 僅為文書編輯器,故我們建議讀者們,應該要熟悉 vim 較佳。
vim 有數種基本的模式,亦即是:
簡單的說,讀者可以將數種模式使用底下的圖示來思考一下相關性:
假設讀者想要嘗試編輯 /etc/services 這個檔案,可以這樣嘗試處理看看:
通過上述的練習,讀者應該會對 vim 有初步的認識。vim 的功能其實不只這些,不過管理員會經常用到的大概就是上述的這些資訊而已。 底下為常用的指令列表:
慣用的指令 | 說明 |
i, [esc] | i 為進入編輯模式, [esc] 為離開編輯模式 |
G | 移動到這個檔案的最後一列 |
gg | 移動到這個檔案的第一列 |
nG | n 為數字,移動到這個檔案的第 n 列,例如 10G 為讓游標去到第 10 列 |
dd | dd 為刪除游標所在行,5dd 為刪除 5 行,ndd 為刪除 n 行 |
yy | yy 為複製游標所在行,5yy 為複製 5 行,nyy 為複製 n 行 |
p | 在游標底下貼上剛剛刪除/複製的資料 |
u | 復原前一個動作 |
:w | 將目前的資料寫入硬碟中 |
:q | 離開 vim |
:q! | 不儲存 (強制) 離開 vim |
讀者大概之要知道這幾個按鈕即可,其他的更進階的功能有用到的時候再到基礎學習篇查閱即可。
包括 RockyLinux 9 ,在 RHEL 8 以後的系統,vim 的版本自動化的太厲害了!加上許多縮排與前後數行提前顯示等等。RockyLinux 9 這一版的 vim 增加更多功能。包括在游標所在行之前、後的 5 行自動先行顯示等等。 不過,對某些人來說,增加這些自動判斷的功能,反而會影響到某些複製、貼上的工作!所以,你可能會想要取消這些特定的功能。 如何取消呢?可以透過 vim 的 :set 功能來處理!
不過,上述的功能設定,都會在下次重新開啟新的 vim 時被還原成預設值。如果你想要每次都生效的設定,那就得要修改家目錄下的 vim 設定檔, 檔名是 ~/.vimrc 喔!在設定檔內,雙引號是註解~如果你以前用過 vim, 而且覺得以前的環境比較適應的話,那可以將你的 ~/.vimrc 內容修訂成為底下的模樣即可:
[student@localhost ~]$ vim ~/.vimrc
" 設定搜尋到的關鍵字為高亮度反白
set hlsearch
" 設定語法檢驗功能
syntax on
" 取消自動搜尋機制
set noincsearch
" 搜尋時,忽略大小寫的差異
set ignorecase
" 設計自動縮排
set autoindent
" 設定自動產生行號
set nu
" 設定 tab 的寬度為 8 個字元
set tabstop=8
" 設定預先顯示的行數為 0,亦即不預先顯示
set scrolloff=0
" 設定不要折行
set nowrap
" 設定游標所在行顯示特殊字樣
set cursorline
儲存後離開,以後你使用 vim 編輯資料時,就會出現類似底下的圖示了!如果不喜歡,就自己修改掉相關的設定吧!
作業硬碟一般操作說明:
作業當中,某些部份可能為簡答題~若為簡答題時,請將答案寫入 /home/student/ans.txt 當中,並寫好正確題號,方便老師訂正答案。 請注意,檔名寫錯將無法上傳!
作業結果傳輸:請以 root 的身分執行 vbird_book_check_unit 指令上傳作業結果。 正常執行完畢的結果應會出現【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字樣。若需要查閱自己上傳資料的時間, 請在作業系統上面使用瀏覽器查詢: http://192.168.251.254 檢查相對應的課程檔案。 相關流程請參考: vbird_book_check_unit