SHELL常用編程小結

【1】SHELL範式
規定一個範式,有利於統一程序風格,增加可讀性。對於編寫SHELL,拷貝修改即可。
範式:
ASSIGN SHELL/指定殼
DESCRIPTION/程序說明
BODY/程序體

擴展:
1 ASSIGN SHELL/指定殼,如果不指定殼,默認使用Bourne SHELL,建議使用KSH
#!SHELL路徑
1.1 CSH
#!/bin/csh
1.2 BSH
#!/bin/sh
1.3 KSH
#!/bin/ksh

2 DESCRIPTION/程序說明
#PROCEDURE NAME/程序名稱
#PROCEDURE FUNCTION/程序功能說明
#AUTHOR/作者
#DATE/開發時間
#INPUT/輸入
#OUTPUT/輸出
#CALL/調用函數說明
#HISTORY/變更歷史

3 BODY/程序體
INCLUDE LIBRARY /包含庫文件
VARIABLE DEFINE/變量定義
FUNCTION DEFINE/函數定義
MAIN/程序入口
3.1 INCLUDE LIBRARY /包含庫文件
. LIBRARY FILE/庫文件名稱
3.2 FUNCTION DEFINE/函數定義
#FUNCRION: FUNCTION NAME
#DESC : FUNCTION DESC
#INPUT : INPUT DESC
#OUTPUT : OUTPUT DESC
FUNCTION()
{

}
3.3 MAIN/程序入口(建議爲)
程序啓動說明
程序執行步驟
程序結束
exit 0

範式樣例:
#!/bin/ksh

#################################################################################
# 程序名 : update.sh #
# 功能簡介: 本程序完成WINV200R002M1D039P2升級 #
# 作者 : zhongwei/20150 #
# 開發時間: 2002-05-05 #
# #
# 函數說明: 函數定義 #
# CheckBackupDir() 檢查備分目錄,不完畢則創建 #
# CheckDbinstallDir() 檢查SMP的數據庫安裝腳本目錄 #
# CheckIfUpgraded() 檢查是否已經升級 #
# UpdateSMPDir() 升級SMP的目錄結構 #
# BackupDb() 備分數據庫的腳本、數據 #
# BackupFile() 備分SMP目錄的文件 #
# UpdateDb() 升級數據庫 #
# UpdateFile() 升級文件 #
# #
# 修改歷史: First Programming #
# 日期 : #
# 作者 : #
# 修改說明: #
#################################################################################

#應用庫函數,要求庫函數文件與當前SHELL同一目錄
. ./comm_func.sh.rc

#定義變量
#程序名稱
ProgName="SMP Platform Upgrade"

#標題
Title="WINV200R002 D039P2"

#目錄和文件定義
WorkDir=`pwd`
LogDir=$WorkDir/log
TempDir=$WorkDir/temp

#日誌與標誌文件
ErrFile=$LogDir/update.err
LogFile=$LogDir/update.log
FlagFile=$LogDir/flag.flg

########################函數定義####################################

####################################################################
# 函數:PrintUsage
# 目的:定義打印用法函數。
# 輸入:
# 輸出:屏幕
####################################################################
PrintUsage()
{
echo "***************************************************************"
echo " NAME : ${ProgName} "
echo " VERSION : ${Title} "
echo " SYSTEM : WIN SMP "
echo " DESC : SMP platform or service upgrade "
echo " NOTICE : "
echo " COPYRIGHT : 2002, HUAWEI Tech. Co. Ltd. "
echo "***************************************************************"
echo " 1. Execute backup operation"
echo " 2. Execute upgrade operation"
echo " 3. Execute rollback operation"
echo " 0. Exit"
echo "Please input operation choice [0-3]:"
}

########### Main ##############

exit 0
##################### END OF PROCEDURE ###############

【2】SHELL編程語法
Script是以行爲單位,我們所寫的Script會被分解成一行一行來執行。而每一行可以是命令、註解、或是流程控制指令等。如果某一行尚未完成,在行末加上"\" ,這個時候下一行的內容就會接到這一行的後面,成爲同一行。

當Script中出現"#"時,再它後面的同一行文字即爲註解,Shell會對其翻譯。 在Script中要執行一個命令的方法和在命令列中一樣,你可以前臺或後臺執行,執行命令時也會需要設定一些環境變量。

Script的流程控制和一般高級語言的流程控制沒有什麼兩樣,也和高級語言一樣有副程式。這些使得Script的功能更加強大。

1 SHELL基本術語與關鍵字
. 當前shell程序相同目錄
.. 當前shell程序的上一級目錄
break 退出for、while、until或case語句
cd 改變到當前目錄
continue 執行循環的下一步
echo 反饋信息到標準輸出
eval 讀取參數,執行結果命令
exec 執行命令,但不在當前shell
exit 退出當前shell
export 導出變量,使當前shell可利用它
pwd 顯示當前目錄
read 從標準輸入讀取一行文本
readonly 使變量只讀
return 退出函數並帶有返回值
set 控制各種參數到標準輸出的顯示
shift 命令行參數向左偏移一個
test 評估條件表達式
times 顯示shell運行過程的用戶和系統時間
trap 當捕獲信號時運行指定命令
ulimit 顯示或設置shell資源
umask 顯示或設置缺省文件創建模式
unset 從shell內存中刪除變量或函數
wait 等待直到子進程運行完畢,報告終止

2變量
Shell的類型只有字串變量,所以要使用數值運算則必須靠外部命令達成目的。而其變量種類有下列幾種:
2.1 普通變量
這是最常使用的變量,我們可以任何不包含空白字元的字串來當做變量名稱。 設定變量值時則用下列方式:
var=string #不能是var = string,即等號兩邊不能有空格。與判斷語句正好相反,判斷語句表的=或者其他符號兩邊必須有空格,否則爲賦值運算
取用變量時則在變量名稱前加上一"$" 號,或者${name}。
name=Tom
echo name
echo $name
結果如下:
name
Tom

2.2環境變量
和使普通變量相似,只不過此種變量會將其值傳給其所執行的命令。要將一使 用者變量設定爲系統變量,只要加上:
export var或者export var=var_value 或者setenv var var_valued
name=Tom
export name

以下是使用者一進入系統之後就已設定好的系統變量:
$HOME 使用者自己的目錄
$PATH 執行命令時所搜尋的目錄
$TZ 時區
$MAILCHECK 每隔多少秒檢查是否有新的信件
$PS1 在命令列時的提示號
$PS2 當命令尚未打完時,Shell要求再輸入時的提示號
$MANPATH man 指令的搜尋路徑

2.3 只讀的使用者變量
和使用者變量相似,只不過這些變量不能被改變。要將變量設成只讀的 ,只要加上:
readonly var

而若只打readonly則會列出所有隻讀的變量(ksh支持readonly命令。csh不支持,但是在shell程序中可以使用readonly修飾某個變量)。還有一點,系統變量不可以設定成只讀的。
name=Tom
readonly name
echo $name
name=John
echo $name
(假設文件保存爲aa)
結果如下:
aaa
aa[4]: name: This variable is read only

2.4 特殊變量
有些變量是一開始執行Script時就會設定,並且不以加以修改,但我們不叫它只讀的系統變量,而叫它特殊變量,因爲這些變量是一執行程式時就有了,況且使用者無法將一般的系統變量設定成只讀的。以下是一些等殊變量:
$0 這個程式的執行名字
$n 這個程式的第n個參數值,n=1..9
$* 這個程式的所有參數
$# 這個程式的參數個數
$$ 這個程式的PID
$! 執行上一個背景指令的PID
$? 執行上一個指令的返回值

$n,n只能爲0-9的原因,是Bourne Shell的位置參數變量爲$1~$9, 因此通過位置變量$n只能訪問前9個參數。當你執行這個程式時的參數數目超過9 時,我們可以使用shift 命令將參數往前移一格,如此即可使用第10個以後的參數。除此之外,可以用set 命令改變$n及$*,方法如下:
set string

如此$*的值即爲string,而分解後則會放入$n。如果set命令後面沒有參數, 則會列出所有已經設定的變量以及其值。
echo Filename: $0
echo Arguments: $*
echo No. of args.: $#
echo 2nd arg.: $2
shift
echo No. of args.: $#
echo 2nd arg.: $2
set hello, everyone
echo Arguments: $*
echo 2nd arg.: $2

結果如下:
Filename: ex1
Arguments: this is a test
No. of args.: 4
2nd arg.: is
No. of args.: 3
2nd arg.: a
Arguments: hello, everyone
2nd arg.: everyone

2.5 數組變量 (ksh支持)
name[index]=value
其中name爲數組名稱,index爲數組下標,在ksh中數組最大支持1024,即index爲0~1023.
或者
set –A name value1 value2…valuen
引用數組變量
${name[index]}
應用所有項:
${name[*]} #或者
${name[@]}

如:
set –A ser pps ppip mvpn
echo ${ser[2]}
echo ${ser[*]}
打印爲:
mvpn
pps ppip mvpn

如:
set –A ser pps ppip mvpn
echo $ser[2]
echo $ser[*]
打印爲:
pps[2]
pps[*]

2.6 SHELL變量
SHELL程序中可以直接使用一些變量。常用有:
SECONDS #ftp程序中判斷超時經常使用這個變量
IFS #域分割符,缺省爲空格或者TAB鍵,可以由用戶指定

3引用
某些字符在SHELL中具備特殊的含義:
如:& * + ^ $ ` " | ? [ ] ; ^ < >
可以使用雙引號或者單引號或者\去掉特殊字符的含義,使成爲一個普通字符.
3.1 ””可以去掉除$, \, ``之外的所有特殊字符的含義。
比如:
>echo * #輸出當前某個的所有目錄與文件
>echo “*” #輸出*字符
>echo “`date`” #輸出爲date命令打印的時間“Tue Sep 17 11:31:58 MDT 2002”
>echo “$PATH” #輸出當前用戶的搜索路徑
>echo “a\na” #輸出爲2行,一行一個a,此時\爲特殊字符
3.2 ‘’單引號可以去掉\去掉引號以內包含的任何特殊字符的含義,使成爲一個普通字符.
比如:
>echo ‘*’ #輸出*字符
>echo ‘`date`’ #輸出`date`
>echo ‘$PATH’ #輸出$PATH
>echo ‘a\na’ #輸出爲2行,一行一個a,此時\爲特殊字符

3.3 \可以去掉& * + ^ $ ` " | ?的特殊含義,\本身的特殊含義可以用\去掉,比如\\後面一個\就是普通字符
如:
>echo \* #輸出*

4標準輸入與輸出
當我們在shell中執行命令的時候,每個進程都和三個打開的文件相聯繫,並使用文件描述符來引用這些文件。由於文件描述符不容易記憶, shell同時也給出了相應的文件名。下面就是這些文件描述符及它們通常所對應的文件名:
文件文件描述符
輸入文件—標準輸入0
輸出文件—標準輸出1
錯誤輸出文件—標準錯誤2
系統中實際上有1 2個文件描述符,但是正如我們在上表中所看到的, 0、1、2是標準輸入、輸出和錯誤

command > filename 把把標準輸出重定向到一個新文件中
command >> filename 把把標準輸出重定向到一個文件中(追加)
command 1 > fielname 把把標準輸出重定向到一個文件中
command > filename 2>&1 把把標準輸出和標準錯誤一起重定向到一個文件中
command 2 > filename 把把標準錯誤重定向到一個文件中
command 2 >> filename 把把標準輸出重定向到一個文件中(追加)
command >> filename 2>&1 把把標準輸出和標準錯誤一起重定向到一個文件中(追加)
command < filename >filename2 把command命令以filename文件作爲標準輸入,以filename2文件作爲標準輸出
command < filename 把c o m m a n d命令以f i l e n a m e文件作爲標準輸入
command << delimiter 把從標準輸入中讀入,直至遇到d e l i m i t e r分界符
command <&m 把把文件描述符m作爲標準輸入
command >&m 把把標準輸出重定向到文件描述符m中
command <&- 把關閉標準輸入

比如常用dbaccess執行一個SQL串:
>dbaccess $TELLIN_DBNAME <$errorfile 2>&1
delete from basetab_pps where msisdn=’13000000000’
EOF

5重新定向
輸入定向:可以從文件或者標準輸入設備得到輸入
<
輸出定向:
> #將命令的屏幕輸出定向到文件
>> #將命令的屏幕輸出定向到文件,採用Append方式
管道定向:
| #將一個命令的輸出定向到另外一個命令的輸出(某些命令不支持直接|定向)
如:將一條SQL輸出到dbaccess執行
>echo “update basetab_pps set multiserviceflag=’00000000000” where msisdn=’13501300000”|dbaccess $TELLIN_DBNAME
>ps –ef |grep “manager” |grep –v “grep” | wc –l #多次管道定向

得到命令返回值,輸出到變量:
var=`command`
如:
>echo Time=`date "+%y-%m-%d %H:%M:%S"` #輸出Time=02-09-17 18:30:06

6基本流程語句
6.1 順序
6.2 條件語句if-then-fi
if condition
then
...
fi

我們經常使用的書寫方式:使用;符號,在一行中包含多條命令與語句
if condition ;then
...
fi

6.3 條件語句if-then-else-fi
If condition
then
...
else
...
fi

if condition1
then
...
elif condition2
then
...
else
...
fi

6.4 while條件循環
while express
do
...
done
#從循環中退出使用 break和continue命令

6.5 for循環
for var in arg1 arg2 ... argn
do
...
done
#從循環中退出使用 break和continue命令

6.6 until循環
until express
do
...

done
#從循環中退出使用 break和continue命令

6.7 case選擇語句
case var in
var1)
...
;;
var2|var3)
...
;;
*)
;;
esac

如升級程序選擇菜單就是利用case建立的:
while true
do
#執行
echo ""
if [ "-${OprChc}" = "-1" ]; then
Backup #備份
elif [ "-${OprChc}" = "-2" ]; then
Upgrade #升級
elif [ "-${OprChc}" = "-3" ]; then
Rollback #回滾
elif [ "-${OprChc}" = "-0" ]; then
Log "Goodbye!"
Log ""
break
else
echo "Invalid input , please input again!"
fi

echo ""
PrintUsage
read OprChc
done

6.8 select選擇語句(ksh支持)
select選擇語句一般與case語句聯合使用,用戶生成用戶交互菜單。語法爲:
select var in value1 value2 value3 … valuen
do

done
select執行時會根據value項生成一個列表,並且每一項之前給一個從1開始遞增的數字。用戶選擇某個數字,相當於選擇value對應項,賦值給var變量。如:
1) value1
2) value2
3) value3

n) valuen
#?

一般do done之間使用case語句。語法擴展爲:
select var in value1 value2 value3 … valuen
do
case $var in
value1)

;;
value2)

;;
value3)

;;

valuen)

;;
*)
esac
done

7 比較操作
比較操作一般用在條件判斷中,以下語法使用條件判斷爲例:
7.1 字符串比較
1)字符串相等比較
if [ $str = “value” ]; then #注意等號兩邊比較有空格,否則爲賦值運算

fi

2)字符串是否爲空
if [ “-$str” = “-” ]; then #-沒有任何含義,只是爲了增加可讀性

fi

if [ “X$str” = “X” ]; then #X沒有任何含義,只是爲了增加可讀性

fi

3)字符串不相等比較
if [ $str != “value” ]; then #注意等號兩邊比較有空格,否則爲賦值運算

fi

if [ ! $str = “value” ]; then #!爲not的含義,即取反

fi

7.2 數字比較
1)大於、大於等於
if [ $str -gt 100 ]; then #-gt表示大於

fi

if [ $str -ge 100 ]; then #-ge表示大於等於

fi

2)小於、小於等於
if [ $str -lt 100 ]; then #-lt表示小於

fi

if [ $str -le 100 ]; then #-le表示小於等於

fi

2)等於、不等於
if [ $str –eq 100 ]; then #-eq表示等於

fi

if [ $str -ne 100 ]; then #-ne表示不等於

fi

if [ ! $str -eq 100 ]; then #!表示取否,-eq表示等於

fi

7.3 判斷條件連接
1)與/and,即要求表達式1與表達式2同時爲真
if express1 && express 2 ; #&&表示與/and含義
then

fi

if [ str1 = “aa” ] && [ str2 = “bb” ] ;
then

fi


2)或/or,即要求表達式1或者表達式2之一爲真
if express1 || express 2 ; #||表示或/or含義
then

fi

if [ str1 = “aa” ] || [ str2 = “bb” ] ;
then

fi

3)取反,
if ! express1 ; #!表示去反
then

fi

if [ ! $? –eq 0 ];
then

fi


8 SHELL函數

可以將SHELL中需要重複執行的代碼寫成函數,與C變成的函數一致。
8.1 函數格式
定義函數的格式爲:
函數名()
{
...
}
或者
函數名(){
...
}
兩者方式都可行。如果願意,可在函數名前加上關鍵字function,建議增加。
function 函數名()
{
...
}

8.2 向函數傳入參數
函數可以帶參數調用,調用方式爲
函數名稱 參數列表

函數取得傳入的參數,與SHELL得到調用的參數完全一致:
判斷參數個數:
$#
取參數:
$1 $2 …

8.3 函數返回參數
函數可以使用return 返回調用參一個值。調用者可以在調用函數後得到函數的返回值:
$?得到,如:
#調用格式:aaa parameter
aaa()
{
return 1
}

#錯誤用法
a=`aaa para` #無法得到返回值1

#正確用法
aaa para
ret=$?

如果使用exit,將退出SHELL程序

8.4 將常用函數寫成庫函數
爲了重複利用代碼,可以將函數寫成庫函數的方式,然後在SHELL中包含進行即可使用:
. libraryfile

9其他基本語法
9.1 條件連接符
and與
命令行:command1 && command2 #如果command1執行成功,執行commnad2
如:rm * && echo "File successfully removed"
(建議不要使用以上語法,因爲語法不常用,可讀性不強)
表達式:express1 && express2
如:if [ $1 -eq 1 ] && [ $1 -eq 1 ]
then
...
fi

or或
命令行:command1 || command2 #僅當前一個命令執行出錯時才執行後一條命令
如:rm * || echo "File removed failed"
(建議不要使用以上語法,因爲語法不常用,可讀性不強)
表達式:express1 || express2
如:if [ $1 -eq 1 ] || [ $1 -eq 1 ]
then
...
fi

9.2 包含庫函數
#. 空格之後將文件的路徑, 一般放在程序的起始部分
. ./comm_func.sh.rc

9.3 信號處理
trap "echo ___ $0 interrupted ___; exit 1" 2

9.4 分割符
SHELL默認的分割符IFS爲空格與TAB鍵。程序中可以使用定製的分割符
如:從dbaccess下載數據沒有指定delimiter時,字段分割爲”|”
OLD_IFS=$IFS
IFS=”|”
Read col1 col2 col3 < datafile

IFS=$OLD_IFS

9.5終端的一些知識
1) 使字符顯示方式正常或者反轉顯示
echo “\033[m\c” #正常顯示
echo “\033[7m\c” #反轉顯示

2)設置圖形模式或者字符模式
echo “\033(B\c” #字符模式
echo “\033(0\c” #圖形模式

3)從終端得到一個字符
TTY=`tty`
$1='`dd if=$TTY bs=1 count=1 2>/dev/null`'

4)定位光標位置
echo "\033[$1;$2H\c" #其中$1表示行,$2表示列

5) 設置終端參數
stty可以用來設置與限制終端屬性,如:終端與計算機之間的傳輸率、退格、中斷等。
echo[-echo] 是否回顯
intr 生成中斷信號,默認使用del按鍵生成
erase 退格鍵,即擦除前面一個字符
【3】常用概念命令與操作
1文件
1.1 文件類型,ls –al 中第一列的第一個字符:
drwxr-xr-x 12 smp20 sms 1024 Aug 13 15:36 .dt
d 目錄。
l 符號鏈接(指向另一個文件)。
s 套接字文件。
b 塊設備文件。比如informix操作的存儲文件爲塊設備
c 字符設備文件。比如/dev/null空設備
p 命名管道文件。即進程通信使用的PIPE文件
- 普通文件,或者更準確地說,不屬於以上幾種類型的文件

1.2 文件權限,ls –al 中第一列的第2-10個字符
(2-4字符) 文件屬主的權限
(5-7字符) 同組用戶的權限
(8-10字符) 其他用戶的權限

1.3 改變權限位
chmod命令的一般格式爲:
chmod [who] operator [permission] filename
who的含義是:
u 文件屬主權限。
g 同組用戶權限。
o 其他用戶權限。
a 所有用戶(文件屬主、同組用戶及其他用戶)。
operator的含義:
+ 增加權限。
- 取消權限。
= 設定權限。
permission的含義:
r 讀權限。
w 寫權限。
x 執行權限。
s 文件屬主和組set-ID。
t 粘性位*。
l 給文件加鎖,使其他用戶無法訪問。
或者:
chmod 權限值 filename
文件屬主 同組用戶 其他用戶
rwx rwx rwx
4+2+1 4+2+1 4+2+1

1.4 目錄權限位
目錄的讀權限位意味着可以列出其中的內容。寫權限位意味着可以在該目錄中創建文件,如果不希望其他用戶在你的目錄中創建文件,可以取消相應的寫權限位。執行權限位則意味着搜索和訪問該目錄

1.5 改變文件的屬主
chown命令的一般形式爲:
chown -R -h owner file
- R選項意味着對所有子目錄下的文件也都進行同樣的操作。- h選項意味着在改變符號鏈接文件的屬主時不影響該鏈接所指向的目標文件。一旦將文件的所有權交給另外一個用戶,就無法再重新收回它的所有權

1.6 umask
umask命令確定了你創建文件的缺省模式。這一命令實際上和chmod命令正好相反
umask命令是在/etc/profile文件中設置的,每個用戶在登錄時都會引用這個文件,所以如果希望改變所有用戶的umask,可以在該文件中加入相應的條目。如果希望永久性地設置自己的umask值,那麼就把它放在自己$HOME目錄下的. profile或.bash_profile文件中。
對於SMP或者SCP,我們定義在.cshrc中,這樣登陸即生效。如:umask 002,這樣創建的文件的權限爲777-002=775

1.7 判斷文件某些特性
-r file #是否存在並且可讀
-w file #是否存在並且可寫
-s file #是否存在並且文件大小大於0
-f file #是否存在並且是規則文件
-d file #是否存在並且爲目錄
-x file #是否存在並且可以執行
-p file #是否存在並且爲管道文件

2數值操作
可以使用:expr或者bc命令,KSH可以使用let
使用 expr 應用程序
2.1 expr
n1=3
n2=5
n=`expr $n1 + $n2 `
注意:+等操作符2側需要使用空格格開

如:
>expr 10000 + 1111 #相加
>expr 10000 \* 1111 #相乘

ksh 中可使用 let
n1=3
n2=5
let n=n1+n2

2.2 bc
使用bc可以計算任意長度的計算,不會溢出
>echo "1000000000000000000000000000000*1111" | bc
111100000000000000000000000000000

3合併與分割
常用的合併與分割命令有:
? sort
? cut
? split

3.1 sort排序
sort -cmur -o 輸出文件 –t 分割符 +n 輸入文件
下面簡要介紹一下s o r t的參數:
-c 測試文件是否已經分類。
-m 合併兩個分類文件。
-u 刪除所有複製行。
-r 逆向排序DESC,默認爲正向ASC

如:將basetab_pps文件按第4個字段逆向排序
sort –t\| -r +3 basetab_pps.unl > basetab_pps.unl.sort
注意:不能使用-t|,因爲|在SHELL中屬於管道符號,需要使用\|

3.2 cut切割
cut用來從標準輸入或文本文件中剪切列或域。剪切文本可以將之粘貼到一個文本文件。
下一節將介紹粘貼用法。
cut一般格式爲:
cut [options] file1 file2
下面介紹其可用選項:
-c list 指定剪切字符數。
-f field 指定剪切域數。
-d 指定與空格和tab鍵不同的域分隔符。
-c用來指定剪切範圍,如下所示:
-c1,5-7 剪切第1個字符,然後是第5到第7個字符。
-c1-50 剪切前50個字符。
-f 格式與-c相同。
-f1,5 剪切第1域,第5域。
-f1,10-12 剪切第1域,第1 0域到第1 2域。

如:從字符串中”aaabb:aaaaa:bbb”將”aaaaa”切割出來
>echo ”aaabb:aaaaa:bbb” | cut –d “:” –f2

3.3 split
split用來將大文件分割成小文件。有時文件越來越大,傳送這些文件時,首先將其分割可能更容易。使用vi或其他工具諸如sort時,如果文件對於工作緩衝區太大,也會存在一些問題。因此有時沒有選擇餘地,必須將文件分割成小的碎片。
Split命令一般格式:
split –output-file-line input-filename output-filename
這裏output-file-size指的是文本文件被分割的行數。Split查看文件時,output-file-line選項
指定將文件按每個最多1000行分割。如果有個文件有2800行,那麼將分割成3個文件,分別有1000、1000、800行。每個文件格式爲x[aa]到x[zz],x爲文件名首字母, [aa]、[zz]爲文件名剩餘部分順序字符組合,

4匹配或者過濾操作
4.1 grep的使用
grep可以從輸入的字符中,過濾某些或者過濾掉某個特定字符的命令。
一般使用爲:
grep “特徵字符串” inputFile
grep –v “特徵字符串” inputFile

4.2 awk命令的使用
awk是可以使用很複雜,但是能完成某些特定功能,並且常使用的一個命令。使用用法:
awk [–F 分隔符] ‘模式’ inputfile
-F可以指定域或者列之間的分割符,如果不指定,使用默認的分割符(空格或者TAB)。比如對於分割unload命令下載的文件, 可以指定 –F |
對於模式中的使用分割符分割後的域,標記$1,$2 . . . $n,$0標識所有的域。
爲打印一個域或所有域,使用p r i n t命令
比如打印當前目錄的所有文件的大小名稱:
>ls –al | awk ‘{ print $5, $9}’ #大小與文件名稱使用空格格開,即$5,$9使用空格連接
>ls –al | awk ‘{ print $5”|”$9}’ #大小與文件名稱使用|格開,即$5,$9使用|連接
使用BEGIN模式打印頭部信息:
>ls –al | awk ‘BEGIN {print “size filename”} { print $5”\t”$9}’ #相當於打印列的標題
使用END模式打印尾部信息:
>ls –al | awk ‘{print $5”\t”$9} END{print “finished”}’ #在列出文件後,加上finished字符

awk中使用正則表達式
awk中正則表達式匹配操作用到的字符有:
\ ^ $ . [] | () * + ?
用法:
awk [-F 分割符] ‘{if (express) 操作}’
即指定域滿足express表達式的行,纔打印出來.
如打印目錄文件中包含sms的文件:
>ls –al | awk ‘{if ( $9~/sms/) print $0}’
如打印目錄文件大小大於100000字節的文件:
>ls –al | awk ‘{if ( $5>100000) print $0}’

awk中還有很多用法,在此不列出來

4.3 sed命令

5信號處理
信號就是系統向腳本或命令發出的消息,告知它們某個事件的發生。這些事件通常是內存錯誤,訪問權限問題或某個用戶試圖停止你的進程。信號實際上是一些數字。下表列出了最常用的信號及它們的含義列出所有信號:
>kill –l
HUP INT QUIT ILL TRAP IOT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1
USR2 CLD PWR VTALRM PROF IO WINCH STOP TSTP CONT TTIN TTOU

一些信號的含義:
1 SIGHUP 掛起或父進程被殺死
2 SIGINT 來自鍵盤的中斷信號,通常是< C T R L - C >
3 SIGQUIT 從鍵盤退出
9 SIGKILL 無條件終止
11 SIGSEGV 段(內存)衝突
15 SIGTERM 軟件終止(缺省殺進程信號)

5.1 發出信號:
kill –信號 進程號
註明:kill –9 進程號 殺死進程時,操作系統直接將進程從內核清除,不作退出的處理

5.2 檢測信號或者捕捉信號
有些信號可以被應用程序或腳本捕獲,並依據該信號採取相應的行動。另外一些信號不
能被捕獲。例如,如果一個命令收到了信號9,就無法再捕捉其他信號。
當腳本捕捉到一個信號後,它可能會採
取下面三種操作之一:
1) 不採取任何行動,由系統來進行處理。
2) 捕獲該信號,但忽略它。
3) 捕獲該信號,並採取相應的行動

如果需要捕捉信號後,採用自定義的操作,可以使用trap命令:
trap name signal(s)
其中,name是捕捉到信號以後所採取的一系列操作。實際生活中, name一般是一個專門用來處理所捕捉信號的函數。Name需要用雙引號(“ ”)引起來。Signal就是待捕捉的信號。
下表列出了一些最常見的trap命令用法:
trap "" 2 3 忽略信號2和信號3,用戶不能終止該腳本
trap"commands" 2 3 如果捕捉到信號2或3,就執行相應的commands命令
trap 2 3 復位信號2和3,用戶可以終止該腳本

如:收到3( SIGQUIT 從鍵盤退出),打印一行“proc received SIGQUIT and exit”
#!/bin/ksh

trap “fun_exit” 3

fun_exit()
{
echo “proc received SIGQUIT and exit”
exit 1
}

echo “start running”

exit 0

6 eval命令
eval命名可以執行之後跟隨的命令或者變量所賦的值或者表達式。比如:
用法1:
eval echo “aaa”
用法2:
command=env
eval $env
command=”echo aaa”
eval $command
用法3:
value=0
eval [ $? -gt $value ]&&j=1
eval [ $? -gt $value ]&& echo “successfully”
eval var=$#
eval命令在執行程序運行過程中賦值命令的變量非常有用。比如在SHELL編制的人機交互界面中,選中某個菜單項後執行沒個命令或者函數,腳本本身不可能爲每個菜單項case一遍。

【4】其他
4.1 使用不同的殼執行命令文件
1) 如果Script的第一個非空白字元不是"#",則它會使用Bourne Shell。
2) 如果Script的第一個非空白字元是"#"時,但不以"#!"開頭時,則它會使用C Shell。
3) 如果Script以"#!"開頭,則"#!"後面所寫的就是所使用的Shell,而且要將整個路徑名稱指出來,這裏建議使用第三種方式指定Shell ,以確保所執行的就是所要的。Bourne Shell的路徑名稱爲/bin/sh ,而C Shell 則爲/bin/csh。 我們一般使用ksh, 路徑爲/bin/ksh

4.2 使用不同SHELL的區別
BSH:
設置環境變量使用export var=var_value; var=var_valu; export var
CSH/KSH:
設置環境變量使用setenv var var_value

一些KSH獨有的特徵:
1)KSH環境變量
HISTSIZE:歷史命令數量,默認爲128,可以在.chsrc中將其設置爲其他值
TMOUT :超時自動退出,用於一段時間沒有鍵入命令,強制退出
1) 別名
可以定義自己的標識,標識定義的命令。比如:
alias dba dbaccess $TELLIN_DBNAME
2) 支持數組變量

4.3 SHELL程序的返回值不能超出255,否則返回值將不確定

4.4 read命令將輸入的多餘的part給最後一個變量
>read var1 var2
aa bb cc
>echo $var1
aa
>echo $var2
bb cc

4.5 調試
使用-x
1) 在SHELL程序指定執行爲調試模式
#!/bin/sh –x

2) 在命令行中指定調試模式執行
指定SHELL –x 程序名稱,如:
sh –x update_iuser214.sh

4.6 執行SHELL
前臺執行:
>sh 程序名稱
>程序名稱
後臺執行:
>sh 程序名稱 &
>程序名稱 &

4.7 移植性
目前智能業務部的設備選型中,小型機從IBM/HP/SUN 3家中選擇。相應我們的SHELL一般需要在AIX,HP-UX,SunOS上應當保持一致。即SHELL程序一般需要在3中操作系統上進行移植。
可以使用uname –s確定機器的操作系統,比如:
#機器類型
OsType=`uname -s`
if [ "-$OsType" = "-SunOS" ]; then

elif [ "-$OsType" = "-HP-UX" ]; then

elif [ "-$OsType" = "-AIX" ]; then

else
echo "ERROR: system not support this machine type $OsType"
eixt 1
fi

大部分常見的UNIX命令在以上3中操作是一致的,但是某些命令則具有差異(如ftp的ls在HP-UX爲nlist)。如果碰到與操作系統相關的地方,則需要根據操作系統作相應處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章