programmer 常利用 shell 控制核心提供工具來讓電腦正常工作,算是 programmer 的必備技能,那就開始吧!
2018.1.18 說明排版優化
一、命令列基本操作
1.1 系統基本訊息
$ uname -a # 顯示系統核心資訊 $ cat /proc/cpuinfo # 顯示 CPU 資訊 $ cat /proc/meminfo # 顯示 memory 資訊 $ df -h # 顯示磁碟空間資訊 (Disk Free) $ free # 顯示記憶體與 Swap 區的用量 $ whoami # 顯示目前使用者 $ w # 顯示上線使用者清單 $ shutdown # 通知線上使用者關機的時刻後關機。 $ halt # 關機。 $ reboot # 重新開機。 $ man [command] # 顯示命令的手冊內容 $ man -k [keyword] # 顯示含有關鍵字的手冊
正常的關機程序如 shutdown, reboot, halt 等指令都會呼叫特殊的 sync 進行記憶體資料回寫同步作業以確保資料的正確。
1.2 快捷鍵
Tab # 命令補全及檔案補齊 $ !! # 再次執行上一個命令 $ echo [str] # 顯示變數內容或文字 Ctrl+C # 中止執行中的命令 Ctrl+Z # 將執行中的命令丟到背景繼續執行 Ctrl+R # 搜尋執行過的命令 Ctrl+A # 游標移回開頭位置 Ctrl+E # 游標移回最後位置 Ctrl+U # 剪下游標前方所有文字並複製到暫存剪貼簿 Ctrl+K # 剪下游標後方所有文字並複製到暫存剪貼簿 Ctrl+Y # 由暫存剪貼簿貼上 Ctrl+U 與 Ctrl+K 剪下的文字 Ctrl+W # 刪除游標前方的單字 Ctrl+D # 登出 Terminal,同 exit 命令 Ctrl+Shift+C # 複製標示區的文字到剪貼簿 Ctrl+Shift+V # 貼上剪貼簿文字到Terminal裡
1.3 檔案與目錄
$ ls # 顯示目前所在目錄的檔案清單 (LiSt) $ ls -l # 顯示長格式以呈現更多檔案資訊 $ ls -al # 以長格式顯示包含隱藏檔在內的所有檔案 $ pwd # 顯示目前位置 (print Working Directory) $ cd [dir] # 切換目錄 (~ 為家目錄、/ 為根目錄、. 為此層目錄、.. 為上層目錄) $ cd - # 切換目錄到前一個目錄 $ mkdir [dir] # 建立目錄 $ rm [file] # 刪除檔案 (ReMove) $ rm -r [dir] # 刪除目錄 (recursive) $ rm -f [file] # 強制刪除檔案或目錄 $ cp [file1] [file2] # 複製檔案1為檔案2 $ cp -r [dir1] [dir2] # 複製目錄1為目錄2 $ mv [file1] [file2] # 改名/搬移 $ mv [code] [code.bak] # 簡易備份! $ ln [src] [dest] # 建立 hard link $ ln -s [src] [dest] # 建立 symbolic link $ mount # 查看所有掛載資訊 $ mount -a # 掛載 /etc/fstab 中的所有設備 $ mount [dir] # 掛載 /etc/fstab 中某樣設備 $ mount -t nfs [url/ip]:[src_dir] [dest_dir] # 使用 mount 指令掛載 [url/ip] 上的共享 NFS 目錄 $ umount [dir] # 卸載某目錄 $ touch # 修改檔時間戳記或新建一個不存在的檔案 $ cat # 顯示檔案內容(conCATenate) $ cat [file1] [file2] > [file3] # 連接檔案1與檔案3的內容並輸出為檔案3 $ more [file] # 顯示檔案內容並做分頁處理 $ head -[num] [file] # 顯示檔案開頭 [num] 行內容 $ tail -[num] [file] # 顯示檔案倒數 [num] 行內容 $ tail -f [file] # 監看檔案新增的內容,常用於正在改變的日誌檔。
用 export 指令增加環境變數路徑 export PATH=\$PATH:[path],使用 echo \$PATH 指令顯示其內容,可將 export 指令加入 /etc/profile 或 .bashrc 檔案來預設讀入該路徑。
[用心去感覺] symbolic link 和 hard link
Hard link 是真正的資料連結,是多個文件連接到同一個 inode (Linux 每個文件都有一個 inode 存放 block 訊息),所以從檔案系統看是一模一樣的。Hard link 有以下特性:
- 刪除一個 hard link 檔文件並不會消失,除非全部 hard link 都刪除。
- 不能跨檔案系統。
- 不能連結目錄。
Symbolic link 則類似 windows 的連結,產生一個新的文件 (會建立新 inode) 來指向另一個指定的文件,當連結的檔被刪除後,symbolic link 的檔案會和 windows 的連結一樣無法開啟。
1.4 標準輸入輸出的轉向
$ [cmd] < [file] # 終端機輸入資料由檔案輸入 $ [cmd] > [file] # 輸出結果至一個檔案,如果檔案存在則覆蓋。 $ [cmd] >> [file] # 輸出結果至一個檔案,如果檔案存在則加到檔案最後。 $ [cmd] >>&! [file] # !忽略系統警告訊息,&輸出報錯的結果 $ [cmd] 1>[file] 2>[error] # 將結果存入 [file],錯誤輸出存入 [error]
二、搜尋指令
以文本為導向的 linux 系統常需要用搜尋或字串剖析等方法來獲取想要的資訊,因此很多linux 工具像 find, grep, awk, wc, pipe ... 都要熟練才能有效率的操作 linux 系統。
2.1 grep
grep (Global Regular Expression Print) 是一個強大的文本搜尋工具,他能使用表達力極強的正則表達式把匹配的樣式用標準輸出來輸出。
$ grep [parameter] [pattern] [filename] $ grep -irn [pattern] # 無腦使用:在所在目錄下搜尋所有檔案的指定樣式 -i # 忽略字元大小寫的差別 (Ignore-case) -r # 遞迴搜索 (Recursive) -n # 在符合樣式的行前,標示出該行的列數編號。 (Number) ## 其他常用參數 -A [num] 列出符合行之外的後 [num] 行。(After) -B [num] 列出符合行之外的前 [num] 行。(Before) -C [num] 列出符合行之外的前後 [num] 行。 -c 不顯示符合樣式行,只顯示符合的總行數。(Count) -i 忽略大小寫,包含要搜尋的樣式及被搜尋的檔案。(Ignore-case) -E 採用更正式的正則表示式法解釋樣式。(Extended-regex) -f [filename] 將要欲搜尋樣式寫入至樣式檔再以該檔搜尋 (一行一個樣式)。 ## 範例 $ cat [targetfile].txt | grep -f [patternfile].txt # 讀取關鍵字對目標檔案進行搜索 $ [command] | grep [pattern] # 在命令輸出裡搜尋符合樣式的內容 $ ps aux | grep sys -c
常與搜尋樣式搭配的 regular expression 可參考這篇。
2.2. find
$ find [path] [expression] # find 表示法 $ find [path] -name [pattern] # 搜尋檔名 $ find [path] -type [f/d/l/s/...] # 搜尋特定種類檔案 $ find [path] -size [+/-][num][K/M] # 搜尋檔案大小範圍 $ find [path] -[mtime/atime/ctime] [-num/num/+num] # 搜尋特定時間 $ find [path] -perm [perm_num] # 搜尋權限為 [perm_num] 的檔案 $ find . -size +100k -and \( -name "*.txt" -or -name "*.md" \) # 列出當前目錄下檔案大小超過 100kB 的 txt 或 md 檔。 $ find . -iname "*.txt" -exec cp {} /target/path/ \; $ find . -iname "*.txt" | xargs I {} cp {} /target/path/ # 找尋當前目錄下的 txt 檔並將其複製到目標路徑
三、權限設置
3.1 使用者身份切換
使用者身份切換主要有兩個工具:
$ su # 轉換用戶身份。 $ sudo # 不需要 root 密碼而可執行 root 權限的工具。
常見的 su 用法:
$ su # 轉換身份為 root,但 shell 環境是原使用者。 $ su - # 轉換身份為 root,而 shell 環境切換成 root。 $ su -l [user] # 轉換使用者身份,且使用 user 所有相關環境設定檔。 $ su -m [user] # 轉換使用者身份,但用目前的環境設定,不重新讀取新使用者的設定檔。
常見的 sudo 用法:
$ sudo -i # 切換到 root,且使用 root 相關環境變數和設定檔。 $ sudo -i -u [user] # 切換到 [user] 使用者,且使用 [user] 相關環境變數和設定檔。 $ sudo -i -u [user] [command] # 切換到 [user] 使用者執行命令,且使用 [user] 相關環境變數和設定檔。 $ sudo -u [user] [command] # 切換到 [user] 使用者執行命令。 $ sudo -u #[num] [command] # 切換到 #[num] 使用者執行命令。
執行 sudo 時,系統會主動的去尋找 white list (/etc/sudoers),當使用者在 white list 中時,使用者不需再輸入 root 密碼,只需要輸入「使用者自己的密碼」即可登入。
white list 要編輯時,需執行 visudo 來編輯 /etc/sudoers 檔案,visudo 會額外檢查 /etc/sudoers 內部語法以避免使用者輸入錯誤資訊。
white list 要編輯時,需執行 visudo 來編輯 /etc/sudoers 檔案,visudo 會額外檢查 /etc/sudoers 內部語法以避免使用者輸入錯誤資訊。
另外,還有 sudo su, sudo -s, sudo bash ... 等等用法,使用時須釐清環境變數設定檔等問題。
3.2 改變檔案使用者與群組
用法:
$ groups # show all groups
$ cat /etc/group # show all groups
$ cat /etc/passwd # show all users
$ chgrp [groupname] [file/dir] # change group
$ chown [-R] username[:groupname] [file/dir] # change owner
舉例:
$ cat /etc/group
$ chgrp myGroup temp.txt
$ chown root temp.txt
$ chown -R root /tempDir
$ chown root:myGroup temp.txt
$ chown .myGroup temp.txt // change
3.2 改變檔案使用者與群組
用法:
$ groups # show all groups $ cat /etc/group # show all groups $ cat /etc/passwd # show all users $ chgrp [groupname] [file/dir] # change group $ chown [-R] username[:groupname] [file/dir] # change owner
$ cat /etc/group
$ chgrp myGroup temp.txt
$ chown root temp.txt
$ chown -R root /tempDir
$ chown root:myGroup temp.txt
$ chown .myGroup temp.txt // change
3.3 改變檔案權限
一般用法:
$ chmod [privilege-string] [file / dir] $ chmod [privilege-nums] [file / dir]
常用的 privilege-string 更改操作符號如下:
- u : user
- g : group
- o : other
- a : all
- + : 加入權限
- - : 刪除權限
- = : 設定
- s : setuid (Set user id)
想理解上面的用法,可以先 ls -al 顯示全部檔案的基本資訊:
$ cd / $ ls -al total 108 drwxr-xr-x 24 root root 4096 一 11 06:31 . drwxr-xr-x 24 root root 4096 一 11 06:31 .. drwxr-xr-x 2 root root 4096 一 13 21:10 bin drwxr-xr-x 3 root root 4096 一 11 06:32 boot drwxrwxr-x 2 root root 4096 一 10 15:40 cdrom drwxr-xr-x 18 root root 3940 一 13 21:07 dev drwxr-xr-x 137 root root 12288 一 13 21:10 etc drwxr-xr-x 3 root root 4096 一 10 15:41 home ...
其中欄位判讀方法如下:
檔案屬性 | 硬連結數目 | 擁有者 | 群組 | 大小 | 建檔日期 | 檔名 |
---|---|---|---|---|---|---|
drwxr-xr-x | 3 | root | root | 4096 | Jan 11 06:32 | boot |
檔案屬性共有 10 個字元。第 1 個字元表示檔案類型:
- [ d ] : 目錄
- [ - ] : 檔案
- [ l ] : 連結檔
- [ b ] : 表示裝置檔裡面的可供儲存的周邊設備,例如硬碟;
- [ c ] : 表示裝置檔裡面的序列埠設備,例如鍵盤、滑鼠。
第 2 ~ 10 個字元為權限,3 個字元一組,分別表示了 user、group 和 other 對檔或目錄的許可權。其中,權限字元表示法如下:
可將 3 個字元一組的權限轉為數字表示法 (常用):
因此,常見的 chmod 用法如下:
- [ - ] : 不許可
- [ r ] : Read(r)
- [ w ] : Write(w)
- [ x ] : eXecute(x)
可將 3 個字元一組的權限轉為數字表示法 (常用):
- Read, Write, eXcute == rwx == 4+2+1=7
- Read, eXcute == r-x == 4+1=5
因此,常見的 chmod 用法如下:
$ chmod 777 temp.txt // -rwxrwxrwx $ chmod 755 temp.txt // -rwxr-xr-x $ chmod u=rx temp.txt $ chmod u+x temp.txt $ chmod g+x,o-x temp.txt $ chmod -R 755 /tempdir
[用心去感覺] 注意目錄的權限
讀取一個檔案的基本權限須有:(1) 使用者在該檔案所在的目錄的 x 權限。(2) 使用者對該檔案有 r 權限。
四、壓縮
linux 系統最常見的打包壓縮檔為 .tar、.tar.gz、與 .tar.bz2,打包檔案常常配合壓縮一起使用。
4.1 檔案打包 .tar
tar 可以將很多檔案打包成一個檔案,並沒有提供壓縮的功能。
$ tar -cvf [filename.tar] [dirname] # 打包 (TApe aRchive, Compress, Verbose, archive File) $ tar -xvf [filename.tar] # 解開包裹 (eXpress) $ tar -xvf [filename.tar] -C [dir] # 解開包裹至 [dir] $ tar -xvf [filename.tar] [target_file] # 只解開打包檔案中的 [target_file] $ tar -tvf [filename.tar] # 查看壓縮檔的內容 $ tar -tvf [filename.tar] | grep 'word' # 搜尋壓縮檔的檔名 $ tar -rvf [filename.tar] [append_file] # 加入新檔案至 .tar 壓縮檔
4.2 檔案壓縮 .gz, .bz2
$ tar -zcvf [filename.tar.gz] [dirname] # gz with tar $ tar -zcvf [filename.tar.gz] --exclude=/exclude_dir [dirname] $ tar -zxvf [filename.tar.gz] $ tar -jcvf [filename.tar.bz2] [dirname] # bz2 with tar $ tar -jxvf [filename.tar.bz2] $ gzip [filename] # 將 filename 檔案壓縮為 filename.gz
一些常見的壓縮副檔名:
- [filename].tar.gz:tar 打包檔案,經 gzip 壓縮。
- [filename].tar.bz2:tar 打包檔案,經 bzip2 壓縮。
- [filename].tar.xz:tar 打包檔案,經 xz 壓縮,很新還不常見。
- [filename].Z:compress 壓縮檔,古老不常用。
- [filename].zip:zip 壓縮檔。
五、網路
$ netstat # 本機網路連線基本資訊 (socket、TCP、UDP、IP、ethernet) $ netstat -an | grep "114" | sort $ ifconfig # 查詢與控制網路介面卡 (Interface Configuration) $ ifconfig [interface] # 顯示某網卡參數,如 eth0/lo0。 $ ping -c [num] [ip] # 傳送 ICMP 封包去要求對方主機回應是否存在於網路環境中 $ whois [hostname] # 顯示網域主機資訊 $ host -a [hostname] # 找尋 host ip $ traceroute [hostname] # 顯示連線時經過的路徑 (封包傳遞路徑)。 $ dig [hostname] # 網域 DNS 查詢工具 (Domain Information Groper) $ dig +trace [hostname] # 追蹤全過程 $ vim /etc/services # 服務與 port 的對應資訊 $ wget [url] # 下載網址檔案 $ ssh [username]@[ip] # ssh 連線
[用心去感覺] 簡單練習:MTU 設定
MTU (Maximum Transmission Unit) 網卡傳送資料時的最大傳輸單位。
因為標頭佔用 28 bytes (20 bytes IP header 和 8 bytes ICMP header),所以 ping 往上遞增找到最大值後,要加上 28 才是 Maximum MTU。
$ netstat -i # 顯示系統網路介面資訊 (包含MTU) $ ping -s [num(4)] [host] # ping 指定傳輸單位找最大值 $ ifconfig lo0 mtu 16384 # 將 lo0 網卡 MTU 值更改為 16384
六、process 管理
process:process 就是一個正在運作中的程式。在系統中觸發事件時,都會將其定義為一個 process 給予 PID (Process ID),process 中記錄執行者的權限/屬性參數、程式碼與檔案資料等等。
Ctrl + z 將執行中的程式放到背景並暫停 $ [command] & 直接在背景執行程式 $ [command] > log.txt & 直接在背景執行程式並將 log 寫入檔案 $ jobs 觀察目前的背景工作狀態。 $ bg %[num] 讓工作在背景執行。 (background) $ fg %[num] 將背景工作拿到前景處理。(foreground) $ kill -l 列出可執行的 kill 命令 $ kill -[num] 管理背景中的工作。 # -1 :重新讀取一次參數設定檔(類似 reload ) # -2 :使用者中斷該工作,似 [Ctrl]+c 方法中斷一個工作 # -9 :立刻停止一個工作,不論該工作是否為僵屍程序。 # -15 :停止一個工作 (預設值) $ killall [command name] 刪除所有指定的行程 $ ps -l 顯示行程 (自己 shell 相關 process) $ ps aux 顯示所有系統 process $ ps | grep [string] 搜尋特定 process # ps 的參數很多很複雜,要注意有無負號 - 功能不同。 $ pstree -Aup 顯示 process 之間的相關性。 $ top 依 CPU 佔用率顯示 process 資訊 $ nice -n [nice value] [command] $ renice [nice value] -u [user] $ renice [nice value] -p [pid] # 一般使用者的 nice 值為 0 ~ 19 # root 可用的 nice 值為 -20 ~ 19
七、Linux 目錄樹配置標準:FHS (Filesystem Hierarchy Standard)
FHS 標準,主要定義三段目錄:
- 最上層根目錄 /
- 次層 /usr 及
- 次層 /var 的目錄內容。
各目錄大致內容 (ref):
/ 根目錄
/etc, /bin, /dev, /lib, /sbin 這五個次目錄都要與根目錄一起,不可為獨立的 partition。
/bin 放常用執行檔如:ls, mv, rm。
/boot 放 Linux 核心及開機相關檔案。
/grub 放 grub 開機管理程式。
/dev 放裝置有關的檔案,Linux 把裝置當成檔案看待。
/etc 放系統在開機過程需要讀取的檔案。
/rc.d 記錄開關機過程中的 scripts 檔案。
/init.d 放所有服務預設的啟動 scripts。
/xinetd.d 放一些額外的服務。
/X11 放 X window 有關的設定檔。
/home 使用者的家目錄。
/lib 放 Linux 執行或編譯程式時要使用的函式庫 (library)。
/mnt 軟碟及光碟預設掛載的地方。
/proc 虛擬檔案系統,不佔任何硬碟空間,放置的資料在記憶體中。放系統核心與執行程序的資訊。
/root 系統管理員的家目錄。
/sbin 放系統管理常用的程式如:fdisk, mount。
/tmp 一般使用者暫時存放檔案的地方。
/usr 此目錄包括許多子目錄,用來存放系統指令、安裝程式及套件。
/bin 放使用者可執行的程式執行檔。
/include 放一些套件的 header 檔。
/lib 內含許多程式與子程式所需的函式庫。
/local 升級或額外安裝的程式擺放的目錄,以區分原始系統安裝的程式。
/man 放程式的說明檔。
/sbin 放系統管理員可用之程式。
/src 放核心原始碼。
/share 放安裝的程式及套件。
/doc 放系統說明文件。
/man 放程式說明檔。
/X11R6 X window system 存放相關的目錄。
/var 放系統執行中,常態性變動的檔案。
/cache 程式執行中的暫存檔。
/lib 程式執行中需要使用的資料檔案,例如 rpm 資料庫系統。
/log 登錄檔。
/run 某些程式或服務啟動後會將其 PID 放置於此。
/spool 放一些佇列資料。例如主機收到電子郵件後,放於 /var/spool/mail。
References
De-Yu Wang CSIE CYUT - Linux/Unix 系統
UNIX系統中標準輸出入、錯誤的轉向
http://yu-minspace.blogspot.tw/2008/11/unix.html
Linux常用Terminal命令與快捷鍵參考
http://jdev.tw/blog/3599/linux-terminal-commands-and-shortcuts