2007年10月16日 星期二

命令列程式

命令列程式
命令列程式通常是單獨存在的程式,執行前會先在搜尋路徑中去尋找。

常見的有:

cp, date, who, w, ls, cat, wc, last, mv, mkdir, rmdir, mv, ps, top, df, du, dd
ln, sort, sed, awk, ifconfig, dmesg, hostname, dnsdomainname, chmod, chown, chgrp
cut, grep, kill, more, less, mount, nice, ping, sleep, su, tar, gzip, touch,
uname, basename, dirname, tr, uniq, mail


以下介紹幾個簡單命令的用法

date
用途:顯示 or 設定 系統的日期和時間

用法:



date

結果顯示現在的日期時間

date MMDDhhmmYY

調整時間,格式為 月 MM 日 DD 時 hh 分 mm 年 YY

如: date 080109252002 是將時間調為 2002/08/01 09:25

date +格式

控制日期時間的輸出格式

如: date +'%d %H %M' 將顯示現在的 "日 時 分"

其它進一步的用法,請 man date 查閱線上文件。


who
用途:顯示現在誰登入主機

用法:

who

顯示: ols3 pts/0 Aug 1 13:54

whoami 則顯示自己的登入帳號

ls
用途:列出目錄內容

用法:



ls

結果:列出目前所在目錄的內容

ls -a

結果:列出目前所在目錄的內容,包括隱藏檔。

ls -la

結果:使用長列模式列出目前所在目錄的內容,包括隱藏檔。

其它進一步的用法,請 man ls 查閱線上文件。


cat
用途:連結檔案內容並顯示出來

用法:



cat dataf1

結果:顯示 dataf1 的檔案內容

cat dataf1 dataf2

結果:連結 dataf1, dataf1 的內容,並予顯示。

cat >>urmail.txt

kdkdkdkdkdkdkdkdkdk (Enter)

^D

將 cat 拿來當作簡易編輯器。

其它進一步的用法,請 man cat 查閱線上文件。


wc
用途:計算檔案內字數或列數

用法:



wc -l dataf1

結果:顯示 dataf1 的檔案內共有幾列

wc -c dataf1

結果:顯示 dataf1 共有多少字元。

wc -w dataf1

結果:顯示 dataf1 共有多少句元。

其它進一步的用法,請 man wc 查閱線上文件。


ln
用途:鏈結檔案;ln 提供一個方便的機制,使同一個檔案可以有多個檔名

用法:



ln f1 f2

結果:將 f1 鏈結到 f2 (硬式鏈結),f2 的檔案內容和 f1 一模一樣

ln -s f1 f3

結果:將 f1 鏈結到 f3 (軟式鏈結),f3 是 f1 的別名,取用 f3 時,實際上是存取 f1

ln -sf f1 f3

結果:同上,唯若 f3 早已存的話,將被刪除後再重建一個新的

其它進一步的用法,請 man ln 查閱線上文件。


basename
用途:取得路徑名稱中最後的檔名部份

用法:



basename /usr/local/bin/sftp

結果:出現 sftp

以下可以得到相同結果:

baseNAME.sh #! /bin/sh
# 模擬 basename 指令
bn=${1##*/}
echo $bn

===============
./baseNAME.sh /usr/local/bin/sftp
結果為
sftp



dirname
用途:取得路徑名稱中的目錄部份

用法:



dirname /usr/local/bin/sftp

結果:出現 /usr/local/bin

以下可以得到相同結果:

dirNAME.sh #! /bin/sh
# 模擬 dirname 指令
dn=${1%/*}
echo $dn

===============
./dirNAME.sh /usr/local/bin/sftp
結果為
/usr/local/bin



sort
用途:對文字檔的列做排序

用法:



sort dataf4

結果:將 dataf4 做升冪排序

sort -r dataf4

結果:將 dataf4 做降冪排序

sort -n dataf4

結果:將 dataf4 做升冪排序,但以字串的數值大小為比較的標準

sort -n +2 dataf3

結果:跳過前二欄,以 dataf3 中的第三欄做排序,且以字串的數值大小為比較的標準

sort -nr +2 -t: /etc/passwd

結果:-t: 是說改用 : 為分隔符號,+2 是說跳過前二欄,以 /etc/passwd 中的第三欄做降序排序,且 -n 指示 sort 以字串的數值大小為比較的標準,-r 是降冪排列

其它進一步的用法,請 man sort 查閱線上文件。


uniq
用途:對已排序好的檔案刪除重覆列

用法:



uniq dataf3

結果:若重覆列並未連續擺在一起, 則不會有任何作用

sort dataf3 | uniq

結果:刪除 dataf3 檔中的重覆列

sort dataf3 | uniq -d

結果:挑出重覆列

sort dataf3 | uniq -c

結果:計算每一列的重覆數目

其它進一步的用法,請 man uniq 查閱線上文件。


cut
用途:對檔案的每一列抽出某一部份

用法:



cut -c2 dataf1

結果:抽出 dataf1 中每一列的第 2 個字元

cut -c3-10 dataf1

結果:抽出 dataf1 中每一列的第 3 到第 10 個字元

cut -c9- dataf1

結果:抽出 dataf1 中每一列的第 9 以後的字元

cut -c1-3,22- dataf1

結果:抽出 dataf1 中每一列的第 1 到第 3 個字元、以及第 22 個以後的的字元

cut -d: -f1 /etc/passwd

結果:抽出 /etc/passwd 中的第一欄位,-d: 指示 cut 改用 : 為分隔符號,-f1 是第一欄之意

上述指令可拿來找出所有系統的帳號名稱

cut -d: -f3,4 /etc/passwd

結果:抽出 /etc/passwd 中的第3,4欄位

其它進一步的用法,請 man cut 查閱線上文件。


paste
用途:對檔案以列和列合併

用法:



paste dataf1 dataf2

結果:dataf1 的每一列 和 dataf2 的每一列合併,預設以 TAB 分隔

paste -d'#' dataf1 dataf2

結果:dataf1 的每一列 和 dataf2 的每一列合併,以 # 分隔

paste -s dataf4

結果:dataf4 的每一列自己合併在一起 (-s : same file),預設以 TAB 分隔

其它進一步的用法,請 man paste 查閱線上文件。


tr
用途:轉換或刪除字元

用法:



tr k K < dataf1

結果:dataf1 的 k 換成 K 字元

tr ',' '\n' < ttt

結果:ttt 的 , 號換成 換行字元(\n)

tr -d k

結果:k 字元全刪除

cut -d: -f1-6 /etc/passwd | tr : '+'

結果:將 passwd 的六個欄改以 + 分隔

tr '[A-Z]' '[a-z]' < dataf1

結果:將大寫全換成小寫字母

tr '[a-z]' '[A-Z]' < dataf1

結果:將小寫全換成大寫字母

tr -s ' ' ' ' < dataf1

結果:將多餘的空白移除只剩一個 (-s 是壓擠的意思)

其它進一步的用法,請 man tr 查閱線上文件。


grep
用途:顯示符合樣式的列

用法:



grep A *

結果:將含有 A 這個字元的檔案及列顯示出來

grep -i A *

結果:將含有 A或a 這個字元的檔案及列顯示出來 (-i 是不分大小寫之意)

grep -v La data3

結果:將不含 La 的列顯示出來 (-v 是不包含之意)

grep -l La *

結果:只顯示那些檔案包含 La,不秀出符合的列

grep -n La *

結果:也秀出列號

dmesg | grep eth0

結果:將含有 eth0 的訊息列顯示出來

grep -q keyword filename

結果:若 filename 含有 keyword 則傳回 0 (真),否則傳為非 0

命令執行完之後,它的傳回值放在 $? 這個變數中,只要 echo $? 便可得知成功與否,請記住:0 為成功,非 0 為失敗 !


練習用的資料檔
dataf1 的內容:

John TNC 721 7654321
Marry TCC 678 1234567
Jack KCC 123 ABCDEFG
Bob PTC 345 efghijk
Anne TPC 987 1098643


dataf2 的內容:

Susan XXX 121 1AB57RT
Jeff AAA 478 JaBdkdk
Henry BBB 193 LaLaLaL
Allan DDD 621 Bobojto
Ken JJJ 094 sssssss


dataf3 的內容:

987 XXX 121 1AB57RT
234 AAA 478 JaBdkdk
765 BBB 193 LaLaLaL
512 DDD 621 Bobojto
363 JJJ 094 sssssss
765 BBB 193 LaLaLaL


dataf4的內容:

98
2341
7
51
363


常用的特殊字元
\b 後退
\f 跳頁
\n 換行字元
\r return
\t TAB


一個命令列執行好幾個命令
有二種方式:


每個命令之間用 ; 號隔開

如 ./configure ; make ; make install

每個命令之間用 && 號隔開

如 ./configure && make && make install

問題:這二者有何差別?

&& 表示前一個命令執行成功之後,才會接著執行下一個,這樣可讓我們確保所有的命令是否都成功執行。

這經常運用在自動安裝 script 檔中,以下是我平時使用的自動安裝 Apache 及 PHP 的 script 檔:

#! /bin/sh

tar xvzf apache*.gz &&
tar xvzf php*.gz &&


echo "Configure apache ...." &&
cd apache* &&
./configure --prefix=/usr/local/apache &&
cd .. &&
cd php* &&
./configure \
--with-apache=../apache_1.3.26 \
--with-mysql=/home/mysql &&
make &&
make install &&
cd .. &&

cd apache* &&
./configure \
--prefix=/usr/local/apache \
--activate-module=src/modules/php4/libphp4.a &&
make &&
make install &&

cd ../php* &&
cp -f php.ini-dist /usr/local/lib/php.ini



註: 若一列寫不完,可在該列末尾加上接續符號 \

註: 另有 || 的用法:如 命令1 || 命令2 || 命令3

|| 是或之意,當命令1執行成功時,就不會再往下執行,若命令1執行失敗,才會執行命命2

只有當前面二個命命都執行失敗,命令3 才會被執行

也可以把數個命令弄成一組,然後整組去執行它:

第一種方法:(命令1; 命令2; 命令3; ....)

( ) 會開啟一個子 shell 環境來執行括號中的命令組

以下是把一組命令放入背景中執行:

(sort mydata -o result.txt; procdata result.txt) &

第二種方法:{ 命令1; 命令2; 命令3; .... }

不同的是,此法是把這些命令組在現行的 shell 中執行,而非在子 shell 中執行

注意 { 右方、} 左方都要有空白,每個命令都要以 ';'這個符號結束

命令列郵寄帶檔的方法
以下是將 README 這個檔案郵件帶檔寄給 ols3@www.tnc.edu.tw

#! /bin/sh

# 由命令列寄帶檔的信件

# 方法 1: 使用 uuencode 編碼

例1
uuencode README README | mail -s "test attach msg file" ols3@www.tnc.edu.tw

上述的意思是說:把 README 這個檔案(第一個 README)予以 uuencode 編碼,且將 README (第二個 README) 這個名字寫入編碼檔的檔頭,再交給 mail 寄給收信者。

例2
uuencode nc11nt.zip nc11nt.zip | mail -s "test attach msg file" ols3@www.tnc.edu.tw

# 解碼法: uudecode 編碼檔
# 或由 OutLook Express 等讀取信件的程式自動解碼。

# ------------------------------------------------------------------------------

# 方法 2: 使用 base64 編碼

uuencode -m README README | mail -s "test attach msg file" ols3@www.tnc.edu.tw

# 解碼:
# uudecode 編碼檔
# 或
# uudecode 編碼檔 -o 指定輸出檔名
# 如 uudecode encode.txt -o nc11.zip

WinZip 也可以對 uuencode 編碼檔加以解碼,方法如下:
1. 把 uuencode 檔存為 .uue,若是 base64 編碼可存成 .b64
2. 用 WinZip 開啟編碼檔,即可按一般解壓動作來予以解碼。

=========================================================

# 註: uuencode 的用法例:

uuencode nc11nt.zip nc11nt.zip > p.txt

第一個檔名 nc11nt.zip 告訴 uuencode 要編碼的檔案是那一個,
第二個檔名 nc11nt.zip 是要 uuencode 把該檔名寫入 p.txt 表頭
它會在 p.txt 的第一列出現:
begin 600 nc11nt.zip

這樣子別人收到您的編碼檔,對方才知道您編碼之前的檔案格式為何?
因此,一般而言,uuencode 之後的二個檔名,我們都會弄成一樣。

p.txt 的內容截錄如下:

begin 600 nc11nt.zip
M4$L#!!0``@`(`.B88QW[!E;'=`<``)T2```(````9V5T;W!T+FC%5]MNXS@2
M?8X!_T-A%IAM[#B77LS+-B*T)9'%JE.G3I5.CNBSS"MAA5=&.UH82TOIS=I_Z':(J&_63U8M
M2T\'_4,Z_?3/3QE]^HCK%-<9KI]P_94NK90T,0O_**RD2U/K(AC,:*!S6.IV
MIJ6"=55)PO]K83V9!?E2TM7PEOITK>96V*-@Q'TV93
MM\.[^E3%'1F5YE$^2(NM4[QXOK52#]*1TG2R+$Z6NC[!KN3.SLE\RH*C<"F*
M5"DY6%>WAC">ABQ-CNYV5*=3BB9\@7)S)?N'LE=L.K3%_);6T
MHJ*;>EZI'(]SJ9TDX;J=-3]RI2QH_A3VO87F.4F%]Y80KL,]G:63NIUD+R/D
M[T!X]MT2LHA5AW#XB2KA-QO?AF`3:<&PL3>E62.N$D81Z:.J*II+JIUM[6`I?1M,OXQNI]0;WM&WWGC<&T[OSK'4EP9OD9QH2*W6E8)=1&6%]D\AF5\O
MQOTOV-#[>7`]F-ZQ_Y>#Z?!B,J'+T9AZ=-,;3P?]V^O>F&YNQS>CR04R/9&R
M09AC?Q=BIO3*`,A">J$J%X*_0VX=W*L**L6#1(YS":X4)"@'Y;^?P19R$I71
MRQ#M2SZ?DTN>!NKW1S=W@^'5A^O!S\QTA*^-S^C1*C#+FW>3'TLIH[__XV_T
......省略
M`@`(`%9^1B0K8B6N!%\``%3Q```*``````````$`(`"V@50,`0!H;V)B:70N
M='AT4$L!`A0`%``"``@`H8Y&),B0K1B*"P``D@&L!`')E861M92YT>'102P4&``````D`"0#I`0``,G`
end

==============================================================

用以下方法即可解碼回來:

uudecode p.txt -o nc11.zip

沒有留言: