Home | SmbFTPD | Forum |
|
第二十三章 指令應用 UNIX 系統和 MS Windows 最大的不同點在於 UNIX 系統主要的設定及使用都可以經由命令列的指令來完成。因此,如何活用指令便顯得十分重要。 本章將介紹常用的系統指令,讀完本章後,您將會了解下列各類別的指令使用方式:
23.1 基本 UNIX 指令 23.1.1 概論 在 UNIX 系統中,英文字母的大小寫會被視為不同的東西,因此在輸入指令或檔名時,大小寫的差異要特別注意。一般指令用法的格式大概如下: command [option(s)] [filename(s)] command 是我們要執行的指令。[option] 是我們可以加的參數,用 [ ] 包起來的意思是可以有參數,也可以不加參數。而參數之後,有可能是檔名 [filename],並不是所有指令都要加參數或檔案名稱,不過格式大部份都是依照這種順序。另外,如果要在命令列中以一行輸入多個指令,每個指令間可以用分號 ";" 分開。 23.1.2 man 查看指令的使用說明。例如我們要看指令 man 的使用說明: $ man man 如果我們只知道一個關鍵字,卻不知要使用哪一個指令,我們可以使用參數 k 來查詢。例如我們要查詢 firewall 相關的指令: $ man -k firewall man 在查詢指令說明時,預設會去找 /usr/share/man 目錄下的檔案,如果我們要查詢的指令說明檔並不位於該目錄,我們可以使用參數 M 來指定目錄名稱。例如我們要查詢指定 ab 的用法,該指令的說明檔放在 /usr/local/apache/man ,我們可以使用下列指定: $ man -M /usr/local/apache/man ab 我們看 man 檔案時,常會看到像 man(1) 的格式,其中 (1) 表示該指令的分類。依不同的類別,說明檔會存在 /usr/share/man/ 不同的目錄下。例如 (1) 的檔案是在 man1 的目錄中。如果同一個名稱有二個不同的 man file,分別放在不同目錄,我們也可以加上參數來看不同的檔案。例如 crontab 有二個檔案,一個是 crontab(1),另一個是 crontab(5)。當我們要看 crontab(5) 時,使用下列指令即可: $ man 5 crontab 以下為 man 的類別:
當您使用 man 指令時,所輸出的結果大約如下:
23.1.3 ls 用以查看目錄資訊。 在 UNIX 系統中,/ 代表根目錄。當要使用某個目錄下的目錄時,每個目錄之間要以 / 隔開。例如 /usr/bin 表示根目錄下的 usr 目錄下的 bin 這個目錄。 另外,"." 和 ".." 也有特殊意義。"." 代表目前所在的目錄,而 ".." 表示目前目錄的上一層目錄。 例如,../etc 表示上一層目錄下的 etc 這個目錄。 假設我們要查看根目錄下有哪些檔案: $ ls / 在 shell 中,有些符號代表者特殊的意義,例如 * 表示萬用字元,可以代表零個或多個字元,而 ? 代表一個字元。舉例而言,當我們下達 ls 指令來例出檔案時: $ ls myfile* myfile myfile.exe myfile.txt myfile.txab myfile.abap $ ls myfile.tx? myfile.txt 我們可以看到使用符號 * 時,會列出所有開頭是 myfile 的檔案;而使用 ? 時,只會例出 myfile.txt。 但是當我們使用萬用字元來取代檔案名稱時,例如 ls /m*,它不僅例出符合目錄,還會列出該目錄下所有檔案。這時候我們可以使用參數 d 來讓 ls 只列出目錄而不列出其目錄下的檔案: $ ls -d /m* ls 還有一些常用的參數如下,我們也可以同時使用多個參數,如 ls -lad:
23.1.4 cd 所在目錄的切換。例如要切換目錄到根目錄: $ cd / 切換目錄的方式可以使用絕對路徑或相對路徑名稱。絕對路徑是指從根目錄開始,該目錄所在位置。例如 /usr/bin 就是一個絕對路徑。而相對路徑是指相對於目前所在路徑而言,該目錄的位置。例如 ../usr/bin 表示在上一層目錄下的 usr/bin 這個目錄。另外,符號 "~" 表示使用者的家目錄,如果要回到自己的家目錄,可以使用: $ cd ~ 如果只輸入 cd 和 cd ~ 所代表的意義相同,都是回到自己的家目錄。我們也可以符號 "~" 之後加上使用者名稱,來代表該使用者的家目錄。例如要切換到使用者 jack 的家目錄: $ cd ~jack 另外,如果您使用 tcsh 或 bash,您還可以使用 "-" 來切換二個目錄: $ cd /usr/local $ cd /etc $ cd - $ pwd /usr/local $ cd - $ pwd /etc 23.1.5 pwd 查看目前所在目錄名稱。例如: $ pwd /root 23.1.6 cat 列出文字檔內容。假設我們要查看 /etc/rc.firewall 這個檔案的內容,我們可以使用下列指令來列出: $ cat /etc/rc.firewall 在 UNIX 系統中有一個轉向輸出的觀念。我們可以把指令輸出的結果轉向到其他地方 (如檔案)。一般內定的標準輸出是螢幕,標準輸入是鍵盤。我們可以使用 ">" 符號來將輸出轉到別的地方。例如,我們要將 ls 的輸出結果存成檔案 result.txt: $ ls > result.txt 上面的指令會建立一個檔名為 result.txt 的檔案,並將 ls 的結果置於該檔中。如果所在目錄本來就有一個檔案名為 result.txt, 該檔案原本的內容會被清除。如果我們不想清楚該檔原本的內容,只是要把結果附加在原本的內容之後,可以使用 ">>" 。例如: $ ls >> result.txt 我們可以使用 cat 指定來做簡單的文字檔複製,例如將 /etc/rc.firewall 複製一份到自己根目錄下的 firewall.txt: $ cat /etc/rc.firewall > ~/firewall.txt 另外,我們也可以用 cat 來建立一個文字檔並手動編輯其內容: $ cat >test.txt 在此輸入文字 輸入完後同時按 Ctrl+D 離開 23.1.7 more 以分頁模式來列出文字檔內容。當使用 cat 時,如果檔案超過一頁,畫面一閃而過,看都看不清楚。這時候我們可以使用 more 這個指令來將它分頁輸出。 $ more /etc/rc.firewall 輸出後,我們可以按空白鍵來看下一頁,或按 Q 來離開。 在 UNIX 系統中還有一個觀念是 pipe 管道,就是將一個指令的輸出結果作為另一個指令的輸入。例如,我們要查看 /etc/ 下的所有檔案完整資訊,使用 ls -la /etc 時,發現資訊超過一頁,我們可以使用下列指令: $ ls -la /etc | more "|" 是位於鍵盤右上角倒退鍵附近,和 "\" 同一個鍵的符號。 23.1.8 less less 也是以分頁來輸出檔案內容,和 more 不同的是它在輸出檔案全部內容後並不會離開。我們可以使用 page down 及 page up 鍵來查看,要離開時只要按 Q 鍵即可。 23.1.9 head 列出檔案開頭幾行,預設是輸出檔案開頭的十行: $ head /etc/rc.firewall 我們也可以加上參數 n 來指定要輸出多少行。例如,如果要輸出前二十行: $ head -n 20 /etc/rc.firewall 參數 c 讓我們可以指定要輸出檔案開頭多少 bytes(通常就是多少字元)。例如,如果要輸出檔案開頭前十個字: $ head -c 10 /etc/rc.firewall 23.1.10 tail 列出檔案結尾幾行,預設是十行: $ tail /etc/rc.firewall 我們一樣可以使用 -n 或 -c 來指定要輸出多少行。 23.1.11 w 列出目前在線上的使用者資訊、時間、正在執行的動作等。以下為 w 這個指令的輸出範例: # w 4:32下午 up 20 days, 23:54, 2 users, load averages: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE WHAT root v1 - 4:31下 - top alex p0 192.168.0.2 1:20下 - w 我們可以看到目前系統中有二個使用者登入,分別為 root 及 alex,並分別執行指令 top 及 w。使用者 alex 是使用 telnet 連線,所以我們可以看到他的來源 ip,但 root 從 console 登入,所以在 FROM 欄位中並沒有任何資訊。除了線上使用者資訊外,我們也可以看到系統已開機時間 (這個範例中是 20 天) 及系統負荷等。 23.1.12 who 列出目前在線上使用者的資訊,輸出的欄位和 w 略有不同。其輸出結果如下所示: # who root ttyv1 5 2 16:31 alex ttyp0 5 2 13:20 (192.168.0.2) 23.1.13 date 列出及設定系統時間。如果我們要查看目前時間: $ date 2004年 5月 2日 周日 16時37分12秒 CST date 的輸出結果可能是中文或英文,它會依照您在 .login 或 /etc/csh.login 對於 Locale 的設定而自動調整。 如果我們要設定時間為 2002 年 3 月 12 日 11 點 56 分,我們可以使用下列指令: $ date 200203121156 23.1.14 cal 列出月曆。如果要列出當月月曆: $ cal 我們也可以指定月份,例如列出 2002 年 3 月: $ cal 3 2002 或是列出整年的月曆,例如 2002 年: $ cal 2002 23.1.15 echo 輸出一個字串到標準輸出 (通常是螢幕)。例如: $ echo string 我們也可以將輸出結果轉向到檔案: $ echo 'this is a test' > test.txt 這樣在 test.txt 中就會有一行字串 "this is a test"。 23.1.16 clear 清除螢幕,您也可以使用 [Ctrl] + l 來清除畫面。 23.2 系統管理 23.2.1 ps 在 UNIX 系統中,每個執行中的程式我們稱之為程序 (Process),而 ps 這個指令就是用來看目前系統中正在執行的程序狀態。 $ ps PID TT STAT TIME COMMAND 45836 p0 S 0:00.18 -tcsh (tcsh) 46104 p0 R+ 0:00.00 ps PID 欄位指的是 Process ID,就是這個程序的編號,每個程序的編號都是獨一無二的;TT 是指登入的 tty;STAT 是該程序目前的狀態;而 COMMAND 就是這個程序是那一個指令所執行。 ps 不加任何參數時,只輸出自己在執行的程序,我們可以加上參數 -aux 來列出系統中所有使用者的程序及詳細資料。 $ ps -aux USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 1 0.0 0.1 552 148 ?? ILs 4 2 0:00.17 int root 23 0.0 0.0 208 8 ?? IWs - 0:00.00 adjk alex 6167 0.0 0.8 1332 988 p0 I 7:46 0:00.21 -csh root 6241 0.0 0.8 1332 976 p0 D 8:03 0:00.17 _su 我們來看看第一行所代表的意義:
我們常用的 ps 參數有 auxww 等,其中 a 表示顯示所有的行程,u 表示顯示行程擁有者的資訊,x 顯示 deamon 的資訊,ww 則是顯示完整的 COMMAND 欄位,不要將太長的部份截斷。 23.2.2 kill kill 指令會送出一個訊號 (Signal) 給指定的程序,程序在收到訊號之後,會依其要求來動作。我們常用的訊號如下:
一般而言,每一個程序都會預設接收到訊號是要執行什麼動作,如果我們所送出的訊號在該程序中並沒特別去處理它,則程序會自動結束程式。只有 root 可以管理所有程序,一般使用者只能對自己的程序作 kill。 假設我們要叫 PID 為 123 的程序結束: $ kill -9 123 如果要通知程序重新載入設定檔: $ kill -1 123 23.2.3 top top 是一個好用的程序管理程式,我們可以利用它來秀出執行中的程式。進入 top 之後,我們可以按 "h" 來顯示線上說明或按 "q" 來離開。 我們可以看到 top 的輸出分成二個部份,最上方是目前關於行程的的系統狀態。包含最後一個 PID (last pid)、系統負荷 (load average) 、已開機時間 (up)、總共有多少行程正在執行中、及 CPU 和記憶體的使用量等等。第二個部份和 ps 一樣,列出 PID、行程的擁有者、及其他和行程相關的狀態。 top 這個指令會每二秒自動更新一次。您可以按 "s" 來更改更新時間。 在 top 中,如果我們想要對某個程序執行 kill 的動作,只要按 "k" 再輸入參數及 PID 即可。 23.2.4 systat 用來監看系統資源使用情形。它有幾個常用的參數:
在上述各參數之後,我們還可以指定畫面的更新時間,例如: $ systat -vm 1 進入 systat 之後,我們可以按 Ctrl+L 來重繪畫面,如果要離開 systat 可以先按 : 再打 quit 後離開。 23.2.5 watch 窺視某個 tty 視窗。 當使用者登入系統後,root 可以使用 watch 指令來取得使用者的視窗畫面。也就是說當下達指令後,root 所看到的畫面就會和該使用者一樣。你可以觀察該使用者在做些什麼事,輸出的結果又是什麼。 只有超級使用者 root 可以執行 watch,在執行時,系統會自動載入 snp.ko 這個模組,或者您也可以先在 kernel 中加入下列的設定並重新編譯核心:
並新增 snoop device,使用下列指令: # cd /dev # ./MAKEDEV snp0 snp1 snp2 snp3 接下來就可 watch 指令了。首先,先下指令 w 來看一下站上有哪些使用者。指令結果的第二個欄位部份,有使用者的 tty,例如 p0、v0 等,選定要監看的使用者後,使用 watch ttyp0 來監看該使用者,其中 ttyp0 即該使用者的 tty。你可以使用 CTRL+X 來切換不同的 tty,也可以使用 CTRL+G 離開回到自己的畫面。 23.2.6 alias 這是 Shell 內建的指令,用來建立別名。例如,我們希望下達指令 abc 時,會執行 ls /etc,我們可以使用下列指令: $ alias abc 'ls /etc' $ abc 我們可以使用 unalias 來取消所設定的別名,例如: $ unalias abc 23.2.7 bg 將指定的程序放入背景中執行。當我們下達一個指令後,必須要等待該程式結束後才能輸入下一個命令。如果該程式必須執行一段很長的時間,我們不想等程式結束,可以把它放到背景中執行。 在下達指令後,按 Ctrl+Z 來暫停程式,接著再執行 bg 即可將程式放到背景中執行。 $ sleep 1000 ^Z Suspended $ bg [1] sleep 1000 & $ 我們也可以在所要執行的指令後面加上符號 "&",就可以將該程式放到背景執行: $ sleep 1000 & [2] 46461 23.2.8 jobs jobs 指令可以讓我們查詢目前有哪些程式在背景執行。如果加入參數 -l 可以得到 PID 的資訊。 $ jobs -l [1] + 46459 Running sleep 1000 [2] - 46461 Running sleep 1500 23.2.9 fg 將指定的程序放到前景中執行。我們使用 jobs 看到目前在背景執行的程序之後,可以使用 fg 把它叫回前景。例如要叫回第一個在背景中執行的程式: $ fg %1 sleep 1000 23.2.10 ntpdate 向時間伺服器對時,只有超級使用者才能執行。我們可以使用 ntpdate 這個指令來向時間與頻率國家標準實驗室的時間伺服器對時: # ntpdate -b clock.stdtime.gov.tw 12 Mar 21:24:28 ntpdate[46494]: step time server 210.59.157.30 offset -8.939412 sec 23.2.11 sync 讓系統暫存的資料強制存回硬碟。 23.2.12 shutdown 讓系統在指定的時間關機。如果我們要立即關機可以下指令: # shutdown now 有時候電力公司通知半夜十二點要停電,我們半夜又不想再去使用電腦,這時指定時間關機就發揮作用了。我們可以在白天時先下指令: # shutdown 0203122359 0203122359 表示 2002 年 3 月 12 日 23:59,格式是 yymmddhhmm。在指定關機前五分鐘系統會禁止使用者登入,並且會在 /var/run/ 目錄下建立一個檔名為 nologin 的檔案,內容為拒絕使用者登入時所要告訴使用者的訊息。如果我們要停止 shutdown ,可以送給它一個 SIGTERM,shutdown 程序在收到訊息後,在離開程式前會先刪除 /var/run/nologin 這個檔案。 # ps -ax|grep shutdown 46644 ?? S<s 0:00.00 shutdown 0203122359 # kill -15 46644 shutdown 還有一些參數:
23.2.13 reboot 立即重新開機。 23.2.14 su 切換使用中的使用者身份。例如,我們要從一般使用者切換成 root: $ su Password: # 一般使用者如果要具備切換成 root 的權限,必須在 /etc/group 將它加入在 wheel 群組中。例如,我們要該使用者 jack 可以使用 su 變成 root:
我們也可以使用 su 來切換成不同的使用者,如果加上參數 -l 表示模擬完全 login 的動作。例如,我們要模擬以使用者 foo 登入系統: # su -l foo 我們也可以用參數 -c 來以不同使用者的身份執行一個指令,執行完後切換身份為原本的使用者。例如,我們要以 foo 的身份來執行 sleep 1000 這個指令並放到背景中執行: # su foo -c 'sleep 1000&' 23.2.15 exit 這是 Shell 內建的指令,我們可以使用這個指令來登出系統或登出不同的 Shell。 23.2.16 dmesg 顯示系統訊息暫存區 (message buffer) 的內容。如果是剛開機,暫存區的內容通常就是開機過程的記錄。隨著開機時間越來越長,訊息也會越來越多,開機過程的記錄就會被其他訊息所取代。 23.2.17 lastcomm 顯示使用者曾經執行過的指令。如果要使用這個指令,必須在 /etc/rc.conf 中加入下面這一行:
系統會在 /var/account 目錄下建立記錄檔,如果使用者很多的話,檔案大小將會十分可觀。 如果我們要查看使用者 foo 執行過哪些指令: $ lastcomm foo 這些記錄每天會自動轉檔,存成 acct.0, acct.1 等檔案。如果我們要查詢的是前一天的記錄,可以使用參數 -f 來指定使用哪一個記錄檔: $ lastcomm foo -f /var/account/acct.0 23.2.18 crontab 安排定時執行工作。使用 crontab 可以讓我們安排工作在指定的年、月、日、小時或分的週期來執行。 如果在 /var/cron 目錄中有 allow 這個檔案的話,只有使用者名稱在檔案中的人才可以使用 crontab。如果沒有 allow 這個檔案,但是有 deny 這個檔案的話,被列在 deny 檔案中的人不可以使用 crontab 來安排工作。如果二個檔案都不存在,預設是所有人都可以執行。 我們可以使用 crontab -e 來編輯自己的排程, 使用 crontab -e 的格式,和 /etc/crontab 的格式不太一樣,它少了執行者的欄位,內定的指令執行者就是執行 crontab -e 的人。其格式如下:
執行 crontab 預設會將指令輸出結果寄 email 給執行的使用者,如果我們不希望收到這些結果,可以在檔案開頭加上 MAILTO=""。 另外,我們也可以使用參數 -l 來列出目前執行的 crontab table。或使用參數 -r 來刪除 table。 23.2.19 uptime 顯示系統開機主機狀況。例如: $ uptime 10:51下午 up 8 days, 8:46, 2 users, load averages: 1.01, 1.02, 1.00 出現的資訊依序為現在時間、共開機多久、開機時間、目前使用者有多少人、系統每 1 分鐘、每 5 分鐘、每 15 分鐘的平均負荷 (load)。 23.2.20 sysctl 顯示或設定核心 (kernel) 狀態。使用參數 -a 可以列出目前 kernel 狀態值的設定,例如: $ sysctl -a 我們也可以使用參數 -w name=value 的方式來設定新的值。這些值如下表:
假設我們的系統常出現 file: table is full 的訊息,我們可能要重新編譯 kernel 並提高 maxuser 的值。或者我們也可以使用 sysctl 來做更動。首先我們看一下 kern.maxfiles 的值: # sysctl kern.maxfiles kern.maxfiles: 2024 我們可以使用下列指令來提高它: # sysctl -w kern.maxfiles=16244 如果我們要讓這個設定在每次重開機時都自動載入,可以將該指令放到 /etc/rc.local 中,或是在 /etc/sysctl.conf 中加入下面這一行:
23.3 使用者管理 23.3.1 vipw 編修使用者密碼檔。我們可以使用 vipw 這個指令來編輯使用者密碼檔 /etc/master.passwd。如果我們編輯的內容不符合密碼檔的格式,vipw 會提出警告。在修改完後,vipw 還會自動執行 pwd_mkdb 來更新系統資料庫。 23.3.2 groups 這個指令可以秀出使用者屬於哪一個群組。例如秀出使用者 jack 的群組: $ groups jack wheel jack 23.3.3 adduser 請參考使用者管理一章關於 adduser 指令的介紹。 23.3.4 pwd_mkdb 如果我們直接以文書編輯軟體來修改 /etc/master.passwd,在修改完後,必須執行 pwd_mkdb 來將更新的資料做成系統可以讀取的資料庫檔。pwd_mkdb 還會自動建立 /etc/passwd。 23.3.5 rmuser 刪除使用者。使用 rmuser 將會進行下列動作:
必須要注意的是 rmuser 並不能刪除 UID 為 0 的使用者 (如 root)。 23.3.6 passwd 變更使用者密碼。如果不加使用者名稱,則會變更所登入的使用者密碼。用法如下: # passwd jack 23.3.7 chpass chfn, chsh, chpass 是一樣的東西,用來更改使用者資料,如果以 root 來執行的話,其內容其實就是 master.passwd 的東西。如果以一般使用者執行,使用者可以使用這個指令來修改一些個人資訊。 23.3.8 mesg 是否要允許其他使用者傳送訊息給自己,如果不允許可以使用 mesg n,如果允許則是 mesg y。如果要執行 write 或 talk 必須設為 mesg y。 23.3.9 write 送出訊息給已經登入的使用者。 用法: write user [tty] 例如,要送出一段訊息給使用者 jack: $ write jack 在 jack 的視窗會出現下列訊息: Message from root@foo.com on ttyp0 at 01:39 ... 之後所打的每一個訊息都會出現在使用者 jack 的視窗。 23.3.10 last 顯示使用者登入記錄。例如: $ last mary ttyp0 alex.alexwang 三 3/13 04:01 still logged in foo ttyp1 alex.alexwang 三 3/13 03:54 - 04:01 (00:06) jack ftp alex.alexwang 三 3/13 03:53 still logged in ben ttyp2 alex.alexwang 三 3/13 03:41 - 03:41 (00:00) 如果我們只要顯示某位使用者的登入記錄,我們可以在指令後面加上使用者登入帳號。如果要顯示某一個時間有哪些人在線上,我們可以使用參數 -d。例如,2002 年 3 月 10 日 23:45 時有哪些人在線上: $ last -d 0203102345 last 預設會去找 /var/log/wtmp 這個記錄檔,如果你想要使用其他記錄檔可以加上參數 -f: $ last -f /var/log/wtmp.0 23.4 檔案系統管理 23.4.1 touch 改變檔案存取的時間。例如: $ ls -l -rw-r--r-- 1 jack staff 1520505 2/25 20:12 myfile.txt $ touch myfile.txt $ ls -l -rw-r--r-- 1 jack staff 1520505 3/13 15:21 myfile.txt 在上面的例子中,原本 myfile.txt 的存取日期是 2/25,我們使用 touch 之後,時間變成目前的時間了。如果使用 touch 時有加檔案名稱,但該檔案不存在,touch 會建立一個空的檔案。 我們也可以使用參數 -t 來指定要將存取時間設定為什麼時候。例如,我們要設定為 2002 年 3 月 13 日 23:49: $ touch -t 0203132349 myfile.txt 23.4.2 cp 複製檔案或目錄。 用法: cp 來源 目的 我們可以使用 cp 來複製檔案。例如,將 /etc/services 複製到 ~/services.txt: $ cp /etc/services ~/services.txt 在上面的指令中,如果我們不指定目地檔名,將 ~/services.txt 改成 ~/ 的話,預設會使用原來的檔名,也就是將 /etc/services 複製到 ~/services。我們也可以同時複製多個檔案到一個目錄下,例如複製 /etc/services 及 /etc/rc.conf 到 ~/: $ cp /etc/services /etc/rc.conf ~/ 如果要複製目錄,我們可以使用參數 -R 來將來源目錄及其所有子目錄複製到目的地: $ cp -R sourdir tardir 23.4.3 ln 建立鏈結檔,所謂的鏈結檔就像在 Windows 下的捷徑。如果我們希望同樣一個檔案或目錄可以放在許多地方,我們可以使用 ln 來建立鏈結檔,這樣一來實際存在的檔案只有一個,但在許多地方都有鏈結。例如我們要將 /etc/services 鏈結到 ~/services: $ ln /etc/services ~/services 當我們刪除鏈結檔時並不會影響原本的檔案。鏈結的方式可以分為 Hard link 及 Symbolic link,預設是使用 Hard link。二者的差別在於 Hard link 只能在相同的檔案系統中建立鏈結,而且不能鏈結目錄。我們在分割磁碟時,將不同的目錄建立在不同的分割區上,假設 /etc/services 位於 ad0s1a 而使用者的家目錄 ~/ 位於 ad0s1e,那麼上面指定就不會生效。我們必需使用參數 -s 來建立 Symbolic link: $ ln /etc/services ~/services ln: shit.txt: Cross-device link <---出現錯誤 $ ln -s /etc/services ~/services 我們也可以建立目錄的鏈結: $ ln -s /etc 在上面這個指令中,我們沒有指定目的地,預設會在所在目錄建立鏈結。 23.4.4 mkdir 建立目錄。假設我們要在現行目錄下建立一個目錄 temp: $ mkdir temp 如果我們要建立一個目錄 /tmp/abc/tmp,在是在 /tmp 下並沒有 abc 這個目錄,我們就必須使用參數 -p 來自動建立: $ mkdir /tmp/abc/tmp mkdir: /tmp/abc: No such file or directory $ $ mkdir -p /tmp/abc/tmp 23.4.5 rm 刪除檔案或目錄。例如,我們要刪除 temp 這個檔案: $ rm temp 如果要刪除一個目錄,必須使用參數 -r: $ rm -r /tmp/abc 在刪除檔案或目錄時,如果該檔案是唯讀的,rm 會詢問使用者是否真的要刪除,我們可以使用參數 -f 讓 rm 不要詢問直接刪除。或者我們也可以使用參數 -i 來讓 rm 在刪除檔案時不管是否唯讀都要詢問。 23.4.6 mv 搬移檔案或目錄。例如,我們要將 abc 這個檔案搬到 /tmp/test: $ mv abc /tmp/test 如果在 /tmp/test 存在,而且是一個目錄的話,那麼 abc 會被放在 /tmp/test/abc。 如果 /tmp/test 存在,而且是一個檔案的話,則原來的 test 這個檔案會被刪除,改由 abc 取代之。 我們也可以利用 mv 來更改檔案或目錄名稱。例如,我們要將 abc 改名為 cde: $ mv abc cde 23.4.7 df 顯示磁碟使用情形。 $ df Filesystem 1K-blocks Used Avail Capacity Mounted on /dev/ad0s1a 201518 106212 79186 57% / /dev/ad1s1f 2595662 738200 1649810 31% /home /dev/ad0s1e 2761230 1615176 925156 64% /usr /dev/ad1s1e 503966 11546 452104 2% /var procfs 4 4 0 100% /proc 如果你覺得這樣的輸出結果不容易了解,可以使用參數 -h。我們也可以使用參數 -i 來看 i-node 的使用狀況。 23.4.8 du 磁碟使用情形統計。如果我們要看所在目錄使用多少磁碟空間,可以使用 du 這個指令。和 df 指定一樣,我們可以加參數 -h 來顯示較易閱讀的統計格式: $ du -h /etc 上述指令中,如果不加目錄名稱 /etc,預設是顯示所在目錄的使用統計。我們可以使用 du 這個指定來看系統中所有使用者的家目錄使用情形: # du -sh /home/* 750M /home/jack 60M /home/mary 2M /home/john 如果我們要查出目前系統中使用磁碟空間最大的前5名使用者,我們可以利用 du 搭配 sort 指令: # du -s /home/* | sort -rn | head -5 23.4.9 chmod 改變檔案目錄權限。當我們使用 ls -l 時: $ $ ls -l drwx------ 2 jack staff 512 2/27 02:14 mail/ drwxr-xr-x 2 jack staff 77824 2/22 05:37 txts/ -rw-r--r-- 1 jack staff 1520505 3/11 23:39 myfile.txt drwxr-xr-x 10 jack staff 512 3/11 05:28 software/ 第一個欄位代表的是檔案的權限。該欄位中共有十個字元,第一個字元是檔案的類型,其後每三個字元為一組,分別代表使用者 (User)、所屬群組 (Group)、其他人 (Other) 對於該檔案的存取權限。
在使用 chmod 時,我們可以使用不同的字母來代表使用者 (User)、所屬群組 (Group)、其他人 (Other):
舉例而言,如果我們要讓 myfile.txt 可以讓所有人讀取: $ chmod a+r myfile.txt 如果我們要設定和 myfile.txt 擁有者同一個群組的人可以讀取及寫入該檔: $ chmod g=rw myfile.txt 如果要設定移除群組對 myfile.txt 寫入的權限: $ chmod g-w myfile.txt 另外,我們也可以使用數字來設定檔案權限。r, w, x 都有其對映的數字,以每個使用不同對象為單位,將所對映的數字相加後所得到的數字就是該對象的權限。 圖 23-1 例如,使用者的權限是 rwx,則其權限為 4+2+1=7。而群組的權限是 rx,其權限為 4+1=5。其他人的權限是 r,則以數字表示為 4。我們要設定 myfile.txt 這個檔案的權限: $ chmod 754 myfile.txt 我們來看一下關於目錄的權限,目錄的權限中,如果有 x 表示可以進入該目錄,r 表示可以讀取目錄內容,而 w 則是可以對該目錄寫入。我們用下列的例子來說明目錄權限的應用: $ chmod 500 mydir $ cd mydir $ ls file.txt doc/ mp3/ <--- 權限為 500,沒問題 $ cd .. $ chmod 400 mydir $ cd mydir mydir: Permission denied. <--- 權限為 400,只可以讀不能進入 $ ls mydir file.txt doc/ mp3/ <--- 權限為 400,只可以讀不能進入 $ chmod 100 mydir $ ls ls: .: Permission denied <--- 權限為 100,只能進入,不能看內容 我們上面提及的權限都是以三位數字來表示,另外我們也可以使用四位數字表示。所謂的四位數字是指在原本的三位數之前加上一個關於檔案形態的設定。
假設我們要設定檔案 myfile 可以被所有人讀、寫、執行,並設定 sticky: $ chmod 1777 myfile 23.4.10 chown 改變檔案的擁有人及群組。例如,我們要將目錄 temp 的擁有人設為 jack,並設定群組為 staff: # chown jack:staff temp 如果我們要將目錄 temp 及其下所有檔案及子目錄的擁有人改變成 jack,可以使用參數 -R。 23.4.11 chflags 在 FreeBSD 還有一種特別的權限控制,稱之為「flags」,這些 flags 的設定可以讓我們用來保護特殊的檔案。例如 /kernel 就是一個有設定 flag 的檔案,我們可以使用 ls 加參數 -o 來顯示: # ls -ol /kernel -r-xr-xr-x 1 root wheel schg 2208222 2/26 02:09 kernel flags 的設定淩駕於一般的權限設定,我們可以設定的主要 flags 及其所代表的意義如下:
如果我們要解除所設定的 flags 只要在上述的 flgs 之前加上 no 即可,例如 nouchg。 用法: chflags flags file flags 的設定只有在 kernel security level 為 -1 或 0 時才可以被更改。如果 security level 為 1 或 2 時就不能更動 flags 了。 23.4.12 umask 當我們新增一個文字檔時,預設的檔案權限是 644,而新增一個可執行檔時,預設的權限是 755,也就是除了檔案的擁有人外,其他人都可以讀取或執行。這種預設權限是由 umask 來控制。 我們看一下 ~/.cshrc 的內容:
這裡的設定是 umask 22,也可以表示為 umask 022。022 這三個數字分別代表擁有者、群組、其他人的權限,建立檔案是,將檔案所有權限減去這些數字後,所得到的值就是檔案的預設權限。 例如,一般檔案權限的全部權限是 666,分別減去 022 後,得到的預設權限就是 644。而可執行檔的權限是 777,分別減去 022 後,就是 755。 知道了 umask 之後,或許我們會希望將它設為 077。當然,設為 077 可能會產生一些問題,例如建立一個網頁後,可能沒有辦法讓它在使用者的瀏覽器中出現 (因為執行 apache 通常是以 nobody 或 www 的身份來執行)。 我們可以使用 umask 來顯示目前的設定,或使用 umask num 來設定 umask: $ umask 22 $ umask 77 $ umask 77 23.4.13 diff 比較二個檔案的差異。例如: $ diff file1 file2 23.4.14 wc 計算行數(lines)、字數(words)、位元數(bytes)。我們可以使用這個指令來計算檔案中的字數: $ wc file.txt 77 103 1076 file.txt 輸出結果分別代表行數、字數、位元數,我們也可以使用參數 -l, -w, -c 來指定要輸的是行數、字數、位元數。我們可以將 wc 和 ls 一起使用來計算檔案數: $ ls /etc | wc -l 100 UNIX 指令的好處就在於我們可以自行組合指令創造出新的用法。 23.4.15 whereis 找尋程式的所在。whereis 預設會去尋找標準的二進位檔、說明檔、及原始程式碼檔名符合的檔案。所以我們不能用它來找一般文字檔。 $ whereis netstat netstat: /usr/bin/netstat /usr/share/man/man1/netstat.1.gz 23.4.16 which 在使用者的路徑設定中尋找該程式。 $ which perl /usr/bin/perl 23.4.17 find 在指定目錄下尋找檔案。find 可以用的參數很多:
例如,我們要從根目錄開始,找出 services 這個檔案所在位置: $ find / -name service -print 如果我們要找出檔案大小大於 10M 的檔案: $ find / -size +10485760c -print 如果我們要從所在目錄開始,找出所有副檔名為 bak 的檔案,並將它刪除: $ find . -name '*.bak' -exec rm {} \; 另外,-name 後面可以使用 pattern match,就是用一些名稱規則。例如,我們要找副檔名為 .c、.h、或 .x 或是 .tgz 的檔案: $ find . -name "*.[chx]" -o -name "*.tgz" 我們可以使用參數 -o 來代表 or 而連接多個 -name 的參數。 23.4.18 grep 找尋某一個字串。例如,我們要找 /etc/ 下所有檔案內容有 192.168 這個字串的檔案: $ grep '192.168' /etc/* 我們也可以將 grep 和其他指令一起使用,例如要找出現在執行的程序中 inetd 的 PID: $ ps -aux | grep inetd 23.4.19 tar tape archiver。可以用來壓縮備份檔案。tar 的用法很多,我們僅介紹簡單的壓縮與解壓縮。舊版的 tar 並不具有壓縮功能,只是把檔案包裝成一個磁帶檔。現在的 tar 都可以加上參數 -z 來順便將檔案壓縮。
例如,我們要將目錄 temp 包裝並壓縮成 temp.tgz 這個檔案: $ tar zcvf temp.tgz temp 要解開 temp.tgz: $ tar zxvf temp.tgz 23.4.20 fsck 檢查並修復檔案系統。我們可以指定要修復的檔案系統,或不加任何參數來檢查所有檔案系統。fsck 當檢查發現有問題時,預設會詢問使用者是否要修復,我們也可以加參數 -y 來對於所有問題都回答 y。 # fsck /dev/ad0s1e 23.4.21 mount 掛入檔案系統。如果要掛入的檔案系統在 /etc/fstab 中有記錄,則可以不必指定來源: # mount /usr
例如我們要掛入一個 MS-DOS 的磁片到 /mnt 的目錄中: # mount -t msdos /dev/fd0 /mnt 也可以使用 mount_msdos 指令: # muont_msdos /dev/fd0 /mnt 我們在使用 CD-ROM 之前要先將它掛入,如果是使用光碟安裝 FreeBSD,在 /etc/fstab 中有 CD-ROM 的設定,我們只要執行下列指令: # mount /cdrom 如果沒有,我們要知道光碟機的代號,可以使用 dmesg 來查看開機記錄檔中關於 CD-ROM 的訊息。假設我們的光碟代號是 cd0c,要將它掛入 /cdrom: # mount -t cd9660 /dev/cd0c /cdrom 或是: # mount_cd9660 /dev/cd0c /cdrom 23.4.22 umount 移除掛入的檔案系統。只要輸入 umount mount_point 即可。 CD-ROM 在掛入之後,每法取出光碟片。我們必須使用 umount 來移除才可以將光碟退出: # umount /cdrom 23.5 網路相關指令 23.5.1 ping 檢查遠端系統的連線狀態。ping 指令會送出 ICMP 封包到指定的主機,我們可以藉此來檢查網路連線品質。 常用參數如下:
例如我們要看 www.freebsd.org 的連線品質: $ ping www.freebsd.org PING freefall.freebsd.org (216.136.204.21): 56 data bytes 64 bytes from 216.136.204.21: icmp_seq=0 ttl=54 time=458.986 ms 64 bytes from 216.136.204.21: icmp_seq=1 ttl=54 time=502.258 ms 64 bytes from 216.136.204.21: icmp_seq=2 ttl=54 time=491.489 ms ^C --- freefall.freebsd.org ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 458.986/484.244/502.258/18.393 ms 23.5.2 ifconfig 設定或檢查網路介面。我們可以使用 ifconfig 來顯示所有的網路介面,如果使用參數 -u 表示顯示使用中的網路介面,而 -d 則是非運作中的介面。 我們也可以使用 ifconfig 來讓網路介面運作或停用。 用法: ifconfig [down|up] interface 假設我們要讓網路卡 vr0 停用: # ifconfig vr0 down 我們也可以使用 ifconfig 來設定網路上的 IP 位址。假設要設定 IP 為 192.168.0.1,而子網路遮罩為 255.255.255.0: # ifconfig vr0 192.168.0.1 netmask 255.255.255.0 接著再使用 ifconfig 將 vr0 啟用: # ifconfig vr0 up 23.5.3 arp 顯示 arp 位址。例如我們要顯示 192.168.0.2 這台機器的網路卡號: $ arp 192.168.0.1 23.5.4 traceroute 追蹤由本機到某台主機所使用的路徑。當我們使用 ping 來檢查網路連線狀況時,如果發現無法連線,我們可以使用 traceroute 來檢查到底是網路上的哪一台主機有問題。 $ traceroute www.freebsd.org 23.5.5 netstat 顯示網路狀況。我們可以使用 netstat 來顯示目前的連線狀況。例如: $ netstat -a Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 20 www.ssh 198.z27z4z49.1780 ESTABLISHED tcp4 0 0 *.http *.* LISTEN tcp4 0 0 *.https *.* LISTEN tcp4 0 0 *.smtp *.* LISTEN tcp4 0 0 *.ssh *.* LISTEN tcp4 0 0 *.pop3 *.* LISTEN udp4 0 0 *.syslog *.* udp6 0 0 *.syslog *.* Active UNIX domain sockets Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr cd864e00 dgram 0 0 0 cd84ef0 0 cd864fc0 cd864fc0 dgram 0 0 0 cd84ef0 0 0 我們可以由上面的結果看到目前有一個使用者正使用 ssh 連到我們的網站。經由上表,我們可以看出我們所提供的服務有哪些,目前的使用情形如何。如果我們希望 Foreign Address 直接顯示 IP ,可以使用參數 -n。 我們也可以使用參數 -i 來查看網路介面的使用情形: $ netstat -ai Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll dc0 1500 00:80:c8:f6:b2:66 68890922 15997 8370716 1256 60296 33:33:c0:f6:78:e9 dc0 1500 fe80:1::280 fe80:1::281:c8ff: 0 - 0 - - ff02:1::2:c1f7:78e9(refs: 1) ff02:1::1 (refs: 1) ff02:1::1:ffe7:b266(refs: 1) lp0* 1500 0 0 0 0 0 lo0 16384 34050 0 34050 0 0 我們簡單說明一下各欄位所代表的意義:
23.5.6 sockstat 列出開啟中的 socket。 $ sockstat USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root telnetd 52897 0 tcp4 192.168.0.1:23 192.168.0.2:1969 root sshd 34063 4 tcp4 *:22 *:* nobody httpd 11670 16 tcp4 *:443 *:* nobody httpd 11670 17 tcp4 *:80 *:* root sendmail 117 4 tcp4 *:25 *:* root sendmail 117 5 tcp4 *:587 *:* root inetd 109 4 tcp4 *:21 *:* USER COMMAND PID FD PROTO ADDRESS mysql mysqld 170 6 stream /tmp/mysql.sock root sendmail 117 3 dgram syslogd[100]:3 root syslogd 100 3 dgram /var/run/log 每個欄位所代表的意義如下:
23.5.7 mail 郵件處理程式。古老的 UNIX 郵件處理程式,這個程式對於不熟悉的人使用起來可能有點困難。但是這是在每個 UNIX 系統中都會有的程式,有時在沒有其他選擇的狀況下,我們還是要使用它,至少要知道如何用它來收發信件。 假設我們要寄信給本機的 root: $ mail root 如果我們要寄信給非本機的使用者,可以使用的收件人格式如下:
執行了 mail 之後,程式會先要求我們輸入郵件主旨,輸入後就可以開始打本文了。當完成本文的編輯之後,可以按 Ctrl+D 來將信件送出,或是按二次 Ctrl+C 取消。 我們也可以在執行 mail 時加上參數 -s "subject" 來指定主旨: $ mail -s"hi, my friend" jack@mymail.com 如果我們想要將一個文字檔的內容當做本文送出,例如,我們可以先編輯一個文字檔 content.txt,接著使用下列方式: $ mail -s "hi, my friend" jack@mymail.com < content.txt 說完了寄信,我們來了解一下如何收信。我們可以打 mail 來收信,如果是 root 還可以使用 mail -u user 來收使用者 user 的信件。 $ mail "/var/mail/root": 12 messages 10 unread >U 1 jack Fri Feb 22 03:02 42/690 "Hi friend" U 2 jack Fri Feb 22 03:02 74/2620 "see you tomorrow" U 3 mary@abc.com Sat Feb 23 03:06 570/33527 "don't forget" & 最後面出現的 & 為 mail 程式命令列的提示符號,在第一封信件開頭有一個符號 ">" 表示目前作用中的信件。我們可以直接輸入郵件編號來讀取信件。另外,我們也可以輸入下列指令:
23.5.8 telnnet 使用終端機遠端登入網路上的主機。例如: $ telnet bbs.mgt.ncu.edu.tw 如果在 telnet 時要能輸入中文,必須加上參數 -8: $ telnet -8 bbs.mgt.ncu.edu.tw 23.5.9 ssh 使用 telnet 並未加資料加密,我們很容易在不知不覺中洩露資訊。如果要登入的主機有提供 ssh 登入的話,最好使用 ssh。 用法: ssh username@hostname ssh hostname 例如: $ ssh mary@140.115.77.11 $ ssh jack@mydomain.com $ ssh mydomain.com 只打 hostname 而沒有使用者名稱,登入名稱會是你目前所用的使用者名稱。 如果所連線的主機是第一次連線會出現下列一堆東西,打 "yes" 三個字即可: The authenticity of host '140.115.77.11' can't be established. RSA key fingerprint is 13:93:8a:61:31:df:41:3f:7a:0a:77:ad:7e:49:e7:3f. Are you sure you want to continue connecting (yes/no)? yes 23.5.10 ftp 檔案傳輸程式。如果要登入的主機允許暱名登入,我們使用參數 -a 來自動登入。 $ ftp -a freebsd.csie.nctu.edu.tw 進入 ftp 之後,會出現命令的提示列。我們可以輸入以下的指令:
23.5.11 nslookup 網路主機名稱查詢。如果我們要查詢 www.freebsd.org 所對映的 IP,最簡單的用法是: $ nslookup www.freebsd.org 我們也可以在上述指令最後面加上要查詢的 DNS 主機: $ nslookup www.freebsd.org dns.hinet.net 我們也可以使用 IP 來進入反查: $ nslookup 216.136.204.21 23.5.12 dig 是另一個功能強大的主機名稱查詢工具。簡單的用法如下: $ dig -x 216.136.204.21 $ dig www.freebsd.org 23.5.13 tcpdump 顯示或記錄網路封包。如果要使用 tcpdump,在核心中必須要有 Berkeley packet filter,而且有 /dev/bpf*。如果沒有請在核心設定中加入下面這一行,並重新編輯核心:
執行 tcpdump 後,它會打開指定介面的 promiscuous mode (介面必須支援才有用)。所謂的 promiscuous mode(雜亂模式) 是指不管是否和本機有關的封包都接收進來,要達到這樣的效果,必須藉由 bpf 的支援。 我們可以使用 tcpdump 來觀察到達某一個網路介面的封包。例如我們要監看介面 vr0 的封包: # tcpdump -i vr0 如果要結束直接按 Ctrl+C 即可。 如果限制封包數量,可以使用參數 -c。我們也可以使用參數 -w 來將捕捉到的封包存成檔案,在這裡我們存成 dump 這個檔案: # tcpdump -c 20 -i vr0 -w dump 使用參數 -r 可以讀取儲存的封包資料: # tcpdump -r dump 為了控制 tcpdump 能 dump 我們想要的封包,我們還可以在指令最後加上一些 expression 來控制封包的記錄。關於 expression 的用法請 man tcpdump。 另外介紹一個好用的分析工具 tcpshow, 我們可以使用 ports 來安裝。 # cd /usr/ports/net/tcpshow # make install clean 接著就可以使用 tcpshow 來分析我們儲存的封包內容: # tcpshow <dump | more --------------------------------------------------------------- Packet 8 TIME: 04:53:10.938750 (0.011744) LINK: 00:80:2D:BB:65:38 -> 00:50:AA:00:DC:DD type=IP IP: tw -> 189 hlen=20 TOS=00 dgramlen=44 id=4353 MF/DF=0/1 frag=0 TTL=52 proto=TCP cksum=C56B TCP: port http -> 2451 seq=3298970558 ack=2899053999 hlen=24 (data=0) UAPRSF=010010 wnd=65535 cksum=8549 urg=0 DATA: 我們簡單的說明一下這個封包的內容。第一部份是時間 TIME。 第二行是 LINK,顯示了來源 -> 目的地的網路卡號,另外經由 type=IP,我們知道這是一個 Ethernet_II 的 frame。 第三部份 IP,tw -> 189 是來源及目的地的位址。hlen 是 header length 大小是 20 bytes,而整個 IP 封包 (dgramlen) 的大小是 44 bytes。 第四部份是 TCP,來源是的 port 是 http (內定是 80),而目的地的 port 是 2451。接下來是 TCP 封包的 sequence number 及 acknowledgement 編號。TCP 的 header length 是 24,加上 IP 的 header 20 長度剛好是 44,和 dgramlen 的長度一樣,這個封包應該沒有破損。 最後,這個封包並沒有包含其他的資料。
|