2016
May
06




不管是 Mac 或是 Redhat, freebsd, debian ,這些 unix like 的系統,都有內建其本的 Linux 指令,如果你是 Windows 用戶,可以安裝 Cygwin ,這個軟體能夠在 Windows 上模擬 Linux 系統。

請先登入你的 unix like OS ,開始學習以下的指令吧。

路徑操作 pwd, ls, cd

command description
pwd print working directory
顯示當前目錄
ls list files
顯示檔案列表
ls -l 最出檔案列表明細
ls -lrt 用 modify time 從小到大排序
ls -lrS 用 file size 從小到大排序
cd change directory
改變當前目錄
cd ~ 回到個人目錄
cd - 回到前一個目錄

試試輸入 pwd 然後按 enter ,系統會印出你當前的目錄,例如我的 Account 是 puritys ,平常一登入 Linux 系統,我的當前目錄會是在 /Users/puritys (Mac OS), /home/puritys (Linux)




ps 列出 process 列表

  • ps aux
  • ps auxw
Linux CMD ps
  1. [www]$ ps aux |grep http
  2. USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
  3. root 5424 0.0 3.1 533380 32056 ? Ss 06:01 0:05 /usr/local/sbin/httpd
  4. daemon 5430 0.0 2.5 830840 26132 ? Sl 06:01 0:22 /usr/local/sbin/httpd
  5. daemon 5431 0.0 2.3 830840 24004 ? Sl 06:01 0:20 /usr/local/sbin/httpd
  6. daemon 5432 0.0 2.1 830840 22120 ? Sl 06:01 0:21 /usr/local/sbin/httpd
  7. daemon 5433 0.0 2.6 920684 26728 ? Sl 06:01 0:22 /usr/local/sbin/httpd
  8. daemon 5434 0.0 2.9 920684 29604 ? Sl 06:01 0:21 /usr/local/sbin/httpd

ps 印出來的每個欄位都有它的意義,USER 代表 process 使用的身分, PID 為 process id , CPU、 MEM 代表該 process 使用的比例,TIME 是執行多久, COMMAND 是 process 執行的指令 。

如何找出 CPU 使用量最大的 process.

Example
  1. [www]$ ps aux | awk '{printf "%s %s\n",$3,$11}' | sort
  2. 0.0 sshd:
  3. 0.1 /usr/sbin/notifyd
  4. 0.1 /usr/sbin/ntpd
  5. 0.2 /System/Library/CoreServices/ZoomWindow.app/Contents/MacOS/ZoomWindowStarter
  6. 0.3 /Applications/Google
  7. 5.4 /Applications/Google
  8. 9.0 /Applications/Google

kill & killall

kill 是用來砍掉 process 用的,上面的 ps 範例中,有一個 id 5430 的 httpd process,如果我要中止這個 process ,就可以用 kill 5430.

Linux Command: kill
  1. [www]$ kill 5430
  2. -bash: kill: (5430) - Operation not permitted

一般來說 Linux 系統的 process 是不能隨便中止的,首先要有 admin 的權限,再來要加上 -9 來強迫中止 Process ,看下面這個範例。

Linux Command: kill -9
  1. [www]$ sudo kill -9 5430
  2.  
  3. [www]$ ps aux |grep http
  4. root 5424 0.0 3.1 533380 32056 ? Ss 06:01 0:05 /usr/local/sbin/httpd
  5. daemon 5431 0.0 2.3 830840 24004 ? Sl 06:01 0:20 /usr/local/sbin/httpd
  6. daemon 5432 0.0 2.1 830840 22120 ? Sl 06:01 0:21 /usr/local/sbin/httpd
  7. daemon 5433 0.0 2.6 920684 26728 ? Sl 06:01 0:22 /usr/local/sbin/httpd
  8. daemon 5434 0.0 2.9 920684 29604 ? Sl 06:01 0:21 /usr/local/sbin/httpd
  9. //5430 的 process 成功被中止,而消失了

停掉相同的 process ,Apache server 一次會 fork 出多個 process ,可以用 killall 這個指令來一次刪除所有的 process。

  • sudo killall -9 /usr/local/sbin/httpd

find

find 是 Linux 系統中很常被用到的指令,因為軟體工程師沒辦法記住每一個龐大系統中,每個檔案的路徑,使用 find 可以快速的幫我們找到每一個檔案

  • find [path] -name *.cc
Example
  1. [www]$ find . -name *.js
  2. ./hterm/js/hterm.js
  3. ./hterm/js/hterm_frame.js
  4. ./hterm/js/hterm_keyboard.js
  5.  
  6. [www]$ find /etc/ -name *.conf
  7. /etc//AFP.conf
  8. /etc//apache2/extra/httpd-autoindex.conf
  9. /etc//apache2/extra/httpd-dav.conf

du

du 可以用來計算檔案大小,當系統的硬碟爆炸的時候就會用到它。

Example
  1. [root]$ du -sh /etc/*
  2. 4.0K /etc/AFP.conf
  3. 0B /etc/afpovertcp.cfg
  4. 4.0K /etc/aliases
  5. 0B /etc/aliases.db
  6. 148K /etc/apache2
  7. 0B /etc/asl

計算資料夾大小的時候,可能會有一種需求,就是我不想要記算副檔案為 conf 的檔案,這時就可以用到 --exclude ( Mac OS 不支援這個功能) 。

du --exclude
  1. [root]$ du -sh --exclude *.conf /usr/local/*
  2. 47M /usr/local/bin
  3. 36K /usr/local/builder
  4. 808K /usr/local/sbin
  5. 404M /usr/local/share

cat, zcat

cat 印出檔案原始內容

cat xxx.txt

zcat 印出 gzip 檔的內容,這個指令會先將 tar.gz 解壓縮,然後印出內容。

zcat zzz.gz

tar 打包與解壓縮

tar -zxvf 解開 tar 檔

tar -zxvf xxx.tar.gz

tar -zcvf 將指定的檔案打包成 tar 壓縮檔

tar -zcvf aaa.tar.gz dir/
  • -z 代表用 gzip 加解壓縮
  • -x 解開 tar 檔
  • -c 打包 tar 檔

zip 加解壓縮

gzip test (產生 test.gz)
gunzip test.gz (解開成 test)

tail

即時顯示檔案最新新增的行數

tail -f file

顯示檔案最後 5 行

tail -n 5 file

ctrl+r 搜尋曾經輸入過的指令

ctrl + r 是我超常使用的 Linux 指令,這個指令可以幫你搜尋你最近使用過的 command ,當你按了 ctrl + r ,會看到 reverse-i-search 的訊息,這時你只要輸入你想要搜尋的單母,系統就會在右邊出現 match 到的指令。

例如這個範例,我輸入 ta ,而我最近一次輸入有 ta 字眼的指令是 tail -f ... ,所以系統就會自動幫我找出來,按下 Enter 後,就可以執行這行指令。

Example
  1. [root]$ (reverse-i-search)`ta': tail -f test

當系統已找到我最近使用的指令,這時我可能還想再找更久之前的指令,我們只要再按一次 ctrl+r ,系統就會自動再往前搜尋一次相關的指令。

grep 搜尋文字

grep 是一個很好用的過瀘與文字搜尋指令。

greg -Ri xxx *.txt
grep -l function *.cc
grep -o name *.txt
  • -i case insensitive ,不區分英文字大小寫
  • -o 印出符合的字串
  • -R Recursive
  • -l 印出符合字串的檔名
  • [[:blank:]] grep 空白符號
  • [[:digit:]] grep 數字
  • [[:alpha:]] grep 英文字
Linux command: grep
  1. [www]$ echo "abc def" | grep 'abc'
  2. abc def
  3.  
  4. [www]$ echo "abc def" | grep -o 'abc'
  5. abc
  6.  
  7. [www]$ echo -e "Mars \nFeb \nMonk" | grep 'M'
  8. Mars
  9. Monk
  10.  
  11. [www]$ echo -e "Mars \nFeb \nMonk" | grep 'M\|F'
  12. Mars
  13. Feb
  14. Monk

Awk

awk 是個好用的資料處理指令,一般表格式的資料非常適合用 awk , awk 預設會以空白將資料做分隔,字串會被分割成多個欄位 ,用 $1 代表第一個欄位 ,$2 代表第二個欄位。

首先我要建立一個空白分格的資料,使用簡單的指令 echo -e "a a a\nb b b" ,"\n" 這個符號代表分行,可以資料分成兩行。

再來我用 awk 印出每一行的第一個欄位

Linux Command: awk
  1. [root]$ echo -e "Jackie 50\nMarry 90" |awk '{print $1}'
  2. Jackie
  3. Marry

用 awk 印出每一行的第二個欄位

Linux Command: awk
  1. [root]$ echo -e "Jackie 50\nMarry 90" |awk '{print $2}'
  2. 50
  3. 90

Awk 除了印資料內容之外,也可以用來做資料的加總,範例如下。

Linux Command: awk
  1. [root]$ echo -e "1 \n 2\n 3" |awk '{sum += $1} END {print sum}'
  2. 6

sed

sed 是一個文字 replace 的指令,可以讓我們用簡單的 regular express 取代字串,如果我想把文字裡的 "function " 改成 "public function" ,那麼我可以用 sed 's/string/replace to/g' 這個指令,若是我想要取代某個檔案裡的文字,就只要加上 "-i" 即可。

Example
  1. [www]$ echo "function xxx()" | sed 's/function/public function/g'
  2. public function xxx()
  3.  
  4.  
  5. [www]$ sed -ri 's/function/public function/g' test.php
  6.  
  7.  
  8. // Mac
  9. [www]$ grep -l oauth *.php | awk "{printf \"sed 's/oauth/zauth/g' %s > tmp && mv tmp %s \n\", \$1, \$1}" |sh

time 計算程式執行時間

Example
  1. [www]$ time tcsh -c "repeat 10 php test.php"
  2.  
  3. real 0m2.785s
  4. user 0m0.659s
  5. sys 0m0.141s

合併常用的 Linux 指令

砍掉指定的 process,如果我想要砍掉 vim 跟 php 的所有 process ,那麼我可以用下面這個指令,先用 ps aux 加上 grep 找出 vim, php 的 process ,再用 awk 組出 kill 的指令,最後丟給 sh 處理。

Example
  1. [www]$ ps aux |grep 'vim\|php'|grep -v grep | awk '{printf "sudo kill -9 %s\n",$2}' | sh

將 Apache access log 中的所有 IP, 轉成 hostname 。

Example
  1. [www]$ tail -n 5 access | awk '{print $1}' | sort | uniq | awk '{printf "host %s\n", $1}' | sh
  2.  
  3. 125.233.54.169.in-addr.arpa domain name pointer 7d.e9.36a9.ip4.static.sl-reverse.com.
  4. 78.244.54.169.in-addr.arpa domain name pointer 4e.f4.36a9.ip4.static.sl-reverse.com.
  5. 254.237.178.188.in-addr.arpa domain name pointer 188-178-237-254-static.dk.customer.tdc.net.

將目錄下的所有副檔名為 php 的檔案,副檔名改為 php5 。

Example
  1. [www]$ ls *.php | sed 's/\.php//g' | xargs -t -n 1 -I% mv %.php %.php5
  2.  
  3. mv aaa.php aaa.php5


如何將所有檔案裡的某一個 function 全部取代

假如我碰到一個問題 ,"LOG4CXX_DEBUG" 這個 function 會造成 RHEL4 環境 coredump ,所以我想要把這個 function 都註解掉,首先我用 grep -Rl LOG4CXX_DEBUG * |grep .cc$ 找出所有使用 LOG4CXX_DEBUG 的 C/C++ 檔案。

找出所有的檔案後,再來 sed 來測試取代的語言, grep -Rl LOG4CXX_DEBUG * |grep .cc$ |xargs -t -n 1 cat | sed 's/LOG4CXX_DEBUG/\/\/LOG4CXX_DEBUG/' ,這個指令執行完成後,這時還不會真的修改檔案內容,而是將 replace 後的結果印出來,這樣我們可以先確認印出來的結果是否符何我們的預期。

確定沒問題後,使用 sed -i ,系統就會真的將檔案裡的內容取代。

Example
  1. [www]$ grep -Rl LOG4CXX_DEBUG * |grep .cc$ |xargs -t -n 1 sed -i 's/LOG4CXX_DEBUG/\/\/LOG4CXX_DEBUG/'
  2. sed -i s/LOG4CXX_DEBUG/\/\/LOG4CXX_DEBUG/ client/gServer.cc
  3. sed -i s/LOG4CXX_DEBUG/\/\/LOG4CXX_DEBUG/ client/gServer2.cc
  4. sed -i s/LOG4CXX_DEBUG/\/\/LOG4CXX_DEBUG/ client/gClient.cc
  5. sed -i s/LOG4CXX_DEBUG/\/\/LOG4CXX_DEBUG/ client/gClient2.cc

最後再搜尋一次 LOG4CXX_DEBUG,確認所有的 LOG4CXX_DEBUG 都被註解了。

Example
  1. [www]$ grep -R LOG4CXX_DEBUG *
  2. client/gServer.cc: //LOG4CXX_DEBUG(logger, " xx."<< endl);
  3. client/gServer.cc: //LOG4CXX_DEBUG(logger, "Cannot find "<< __FUNCTION__ << " Line " << __LINE__ << endl);
  4. client/gServer2.cc: //LOG4CXX_DEBUG(logger, "Call xxx "<< __FUNCTION__ << " Line " << __LINE__ << endl);

找出檔案裡的所有英文字

Example
  1. [www]$ cat en |grep -o '[a-z]*' | sort | uniq
  2. said
  3. since
  4. single
  5. the

從 /usr/lib shared object 中掃出某個 function

Example
  1. [www]$ nm -A -C /usr/lib/*.so |grep zero_nan
  2.  
  3. /usr/lib/libm-2.17.so:00030090 r zero_nan
  4. /usr/lib/libm-2.17.so:00032800 r zero_nan
  5. /usr/lib/libm-2.17.so:00034e10 r zero_nan

作業

接下來有一些簡單的作業,看你是否可以完成它囉

  • 移除副檔名 .log ,以及五天前建立的檔案。
  • 計算檔案內的所有不重複英文單字。
  • 計算檔案內的所有中文字數,重複的中文算兩個字。
  • 計算所有 tar, gz, zip 等等的檔案 size 總合。
  • 計算檔案的所有行數,但是不包含空白。
  • 找出 CPU 最多的 process
  • 將檔案內的 call(1, false, 'input') ,改成 apply([1, false, 'input']) 。
  • 移除 PHP 檔案中有使用 error_log 的 function 。
  • 使用 tar ,打包某個檔案,並將其檔案命名為 "年-月-日.tar.gz"
  • 找出檔案內的所有 email 。
  • 印出五天前(120 小時前)的 timestamp。
  • 記算 httpd 這種 process 的記憶體使用量。


回應 (Leave a comment)