1. 程式人生 > >Linux 學習之路(六):bash指令碼編寫

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	
  1. [:space:] ↩︎

  2. [:space:] ↩︎