Linux 學習之路(六):bash指令碼編寫
bash指令碼程式設計:整數測試及特殊變數
exit:退出指令碼
exit #
如果指令碼沒有明確定義退出狀態碼,那麼,最後執行的一條命令的退出碼即為指令碼的退出狀態碼。
bash中常用的條件測試有三種:
測試方法:
命令測試法 [ expression ]
關鍵字測試法 [[ expression ]]
test expression
整數測試:
-gt,-le,-ne,-eq,-ge,-lt
INT1=63
INT2=77
[ $INT1 -eq $INT2 ]
[[ $INT1 -eq $INT2 ]]
test $INT1 -eq $INT2
檔案測試:
-e FILE 路徑:測試檔案是否存在
-f FILE 路徑:測試檔案是否為普通檔案
-d FILE 路徑:測試指定路徑是否為目錄
-r FILE:測試當前使用者對指定檔案是否有讀許可權;
-w:是否有寫許可權
-x:是否有執行許可權
\[ -e /etc/inittab ]
多分支的if語句:
if 判斷條件1; then
statement1
...
elif 判斷條件2; then
statement2
...
else
statement4
...
fi
測試指令碼是否有語法錯誤:
bash -n 指令碼名稱
bash -x 指令碼:單步執行
練習:寫一個指令碼
給定一個檔案:
如果是一個普通檔案,就顯示之
如果是一個目錄,亦顯示之
否則,此為無法識別檔案
#!/bin/bash
FILE=/etc/rc.d/rc.sysinit
if [ ! -e $FILE ]; then
echo "No such file"
exit 6
fi
if [ -f $FILE ];then
echo "Common file."
elif [ -d $FILE ];then
echo "Directory"
else
echo "Unkown"
fi
練習:寫一指令碼
能接受一個引數(檔案路徑)
判定:此引數如果是一個存在的檔案,就顯示“OK”
$1表示指令碼第一個引數
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Usage: ./filetest3.sh ARG1 [ARG2...] "
exit
fi
if [ -e $1 ];then
echo "OK"
else
echo "No such file."
fi
位置變數:
$1,$2,…
shift 輪換/輪替
#!/bin/bash
echo $1
shift 2
echo $1
shift 2
echo $1
練習:寫一個指令碼
給指令碼傳遞兩個引數(整數):
顯示此兩者之和,之積
#!/bin/bash
if [ $# -lt 2 ];then
echo "Usage:cacl.sh ARG1 ARG2"
exit 8
fi
echo "The sum is: $[$1+$2]."
echo "The prod is: $[$1*$2]"
特殊變數:
$?
$# 引數的個數
$* 引數列表
[email protected] 引數列表
sed命令(stream Editor):
流編輯器
基本用法:
行編輯器(全屏編輯器:vi)
模式空間
預設不編輯原始檔,僅對模式空間中的資料做處理;而後,處理結束後,將模式空間列印
sed 'AddressCommand' file ...
-n:靜默模式,不再預設顯示模式空間中的內容
-i:直接修改原檔案
-e SCRIPT -e SCRIPT:可以同時執行多個指令碼
-f /PATH/TO/SED_SCRIPT:
sed -f /path/to/scripts file
-r: 使用擴充套件正則表示式
Address:
1.StartLine,EndLine
比如1,100
$:最後一行
$-1:倒數第二行
2./RegExp/
/^root/
3./pattern1/,/pattern2/
第一次被pattern1匹配到的行開始,至第一次被pattern2匹配到的行結束中間的所有行
4.LineNumber
指定的行
5.StartLine,+N
從startline開始,向後的N行;
Command:
d:刪除符合條件的行;
sed '1,2d' /etc/fstab
sed '/oot/d' /etc/fstab
sed '1,+2d' /etc/fstab 刪除3行
sed '1d' /etc/fstab 只刪除第一行
p:顯示符合條件的行;
sed -n '/^\//p' /etc/fstab 顯示以斜線開頭的行
追加一行:
sed '/^\//a \# hello world' /etc/fstab
a \string:在指定的行後面追加新行,內容為string
i \string:在指定的行前面新增新行,內容為string
r FILE : 將指定的檔案的內容新增至符合條件的行處
w FILE:將指定範圍內的內容另存至指定的檔案中
s/pattern/string/ 修飾符: 查詢並替換,預設只替換每行中第一次被模式匹配到的串
加修飾符
g:全域性替換
i:忽略字元大小寫
s///?###,[email protected]@@
\(\),\1,\2
把行首#換成/
sed 's/^\//#/' /etc/fstab
l...e:like...liker
love...lover
sed 's#l...e#&r#g' sed.txt
後向引用
sed 's#\(l...e\)#\1r#g' sed.txt
like...Like
love...Love
只需用到前面匹配內容的一部分時使用後向引用
sed 's#l\(..e\)#L\1#g' sed.txt
sed命令刪除行首空白字元:(錨定行首,查詢替換空格為什麼都沒有)
history | sed 's#^[[:space:]]*##g'
取出路徑的父目錄
/var/log
sed練習:
1.刪除/etc/grub.conf檔案中行首的空白符;
sed -r ‘[email protected]1[email protected]@g’ /etc/grub.conf
2.替換/etc/inittab檔案中"id:3:initdefault:"一行中的數字為5
sed ‘[email protected]\(id:\)[0-9]\(:initdefault:\)@\15\[email protected]’ /etc/inittab
3.刪除/etc/inittab檔案中的空白行
sed ‘/^$/d’ /etc/inittab
4.刪除/etc/inittab檔案中開頭的#號
sed ‘[email protected]^#@@g’ /etc/inittab
5.刪除某檔案中開頭的#號及後面的空白字元,但要求#號後面必須有空白字元
sed -r ‘[email protected]^#[[:space:]][email protected]@g’ /etc/inittab
6.刪除某檔案中以空白字元後面跟#類的行中的開頭的空白字元及#
sed -r ‘[email protected]2+#@@g’ /etc/inittab
7.取出一個檔案路徑的目錄名稱
echo “/etc/rc.d” | sed -r ‘[email protected](/.*/)[/]+/[email protected]\[email protected]’
基名:
echo “/etc/rc.d” | sed -r ‘[email protected]/.*/([/]+)/[email protected]\[email protected]’
#abc
# hello world
# hi world
我的解答:
1。
[[email protected] /]# sed 's#^[[:space:]]*##g' /etc/grub.conf
1234567
2.
sed 's#(?<=\:)[^\s\:]+(?=\:)#5#' /etc/inittab 存疑
3.
[[email protected] /]# sed '/^$/d' /etc/split.txt
#abc
# hello world
#hi world
4.
[[email protected] /]# sed 's/\#*//g' /etc/split.txt
abc
hello world
hi world
5.
[[email protected] /]# sed 's/\#[[:space:]]//g' /etc/split.txt
#abc
hello world
#hi world
6.
[[email protected] /]# sed 's/.*[[:space:]]\#//g' /etc/split.txt
#abc
# hello world
hi world
7.
字串測試:
==
!=:測試是否不等,不等為真,等為假
>
<
-n string:測試指定字串是否為空,空為真,不空為假
-s string:測試指定字串是否不空,不空為真,空為假
傳遞一個使用者名稱引數給指令碼,判斷此使用者的使用者名稱跟其基本組的組名是否一致,並將結果顯示出來。
if [ `id -n -u $1` == ` id -n -g $1` ];then
echo “Yiyang”
else
echo “Buyiyang”
fi
傳遞一個引數(單字元就行)給指令碼,如引數為q,就退出指令碼;否則就顯示使用者的引數:
#!/bin/bash
if [ $1 = ‘q’];then
echo “Quiting…”
exit 1
elif [ $1 = ‘Q’ ];then
echo “Quiting…”
exit 2
fi
bc 使用scale=2可以保留精度
echo "scale=2;111/22;" |bc
bc <<< "scale=2;111/22;"
寫一個指令碼:
給指令碼傳遞三個整數,判斷其中的最大數和最小數,並顯示出來
MAX=0
MAX -eq $1
MAX=$1
MAX -lt $2
MAX=$2
傳遞3個引數給指令碼,引數均為使用者名稱,將此些使用者的賬號資訊提取出來後放置於/tmp/testusers.txt檔案中,並要求每一行行首有行號。
echo “1 $LINE” >> /tmp/testusers
迴圈:進入條件,退出條件
for
while
until
for 變數 in 列表; do
迴圈體
done
如何生成列表:
{1…100}
`seq [起始數 [步進長度]] 結束數` 注:[]可省
declare -i SUM=0 把變數宣告為整型
從1加到100
#!/bin/bash
declare -i SUM=0
for I in {1..100}; do
let SUM=$[$SUM+$I]
done
echo "The sum is: $SUM"
取出行中每一行並問好。
LINES=`wc -l /etc/passwd | cut -d' ' -f1`
for I in `seq 1 $LINES`; do
echo "Hello,`head -n $I /etc/passwd | tail -1 | cut -d: -f1^`"
done