shell指令碼程式設計基礎

程式設計-浪子發表於2015-05-02

shell程式設計基礎

  • 變數:字串,數字,環境和引數
  • 條件:shell中的布林值
  • 程式控制:if,elif,for,while,until,case
  • 命令列表
  • 函式
  • shell內建命令
  • 獲取命令的執行結果

shell指令碼是一個包含一系列命令的文字檔案.
語法:
#!/bin/sh
符號#!用來指定該指令碼的解析程式.
修改指令碼的屬性:
chmod +x filename


變數

1.引號

#!/bin/sh

myvar="Hi there"

echo $myvar
echo "$myvar"
echo '$myvar'
echo \$myvar

echo Enter some text
read myvar

echo '$myvar' now equals $myvar

exit 0

這裡寫圖片描述

分析: $獲得變數的內容,使用雙引號,不影響變數的替換,使用單引號,反斜線不進行變數的替換.

2.引數變數

引數變數 說明
$# 傳入指令碼的命令列引數個數
$* 所以命令列引數,各個值之間有空格
$@ 各個引數擴充套件彼此分開的域,不受IFS值的影響
$0 命令本身(shell檔名)
$1 第一個命令引數
$2 第二個命令列引數

案例:

#!/bin/sh
echo "number of vars:"$#
echo "values of vars:"$*
echo "value of var1:"$1
echo "value of var2:"$2
echo "value of var3:"$3
echo "value of var4:"$4

這裡寫圖片描述


條件

(1)

if [ expression ]
then
#code block
fi

(2)

if [ expression ]
then
# code block
else
# code block
fi

(3)

if [ expression ]
then
# code block
else if [ pression ]
then
# code block
else
# code block
fi
fi

(4)

if [ expression ];then
# code block
elif [ expression ]
then
# code block
else
# code blcok
fi
fi

字串比較

字串比較 結果
string1 = string2 兩個字串相同,結果為真
string1 != string2 兩個字串不同,結果為真
-n string 字串不為空,結果為真
-z string 如果字串為null,則結果為真

算術比較

算術比較 結果
ex1 -eq ex2 相同結果為真
ex1 -ne ex2 不相等結果為真
ex1 -gt ex2 ex1 > ex2為真
ex1 -ge ex2 ex1 >= ex2 為真
ex1 -lt ex2 ex1 < ex2 為真
ex1 -le ex2 ex1 <= ex2 為真
!ex 表示式結果為假,結果為真

綜合比較

比較操作 整數比較 字串比較
相同 -eq =
不同 -ne !=
大於 -gt >
小於 -lt <
大於或等於 -ge
小於或等於 -le
為空 -z
不為空 -n

檔案條件測試

檔案條件測試 結果
-d file 檔案為目錄為真
-e file 檔案存在
-f file 檔案時普通檔案
-g file 檔案的set-group-id位被設定為真
-r file 檔案可讀
-s file 檔案大小不為0
-u file 檔案的set-urer-id位被設定為真
-w file 檔案可寫
-x file 檔案可執行

案例程式碼:

#!/bin/sh

if [ -f /bin/bash ]
then
    echo "file /bin/bash exists"
fi

if [ -d /bin/bash ]
then
    echo "/bin/bash is a directory"
else
    echo "/bin/bash is NOT a directory "
fi

控制結構

1.for迴圈

for var in [list]
do
code block

done

其中$var是迴圈控制變數,[list]是var需要遍歷的一個集合,do/done對包含了迴圈體,相當於C語言中一對大括號.若do 和 for 寫在同一行上,需要用”;”.
案例程式碼:

#! /bin/sh

for day in Sun Mon Tue Wed Thu Fri Sat
do 
    echo $day
done
exit 0

注意: 在for迴圈那行,變數day是沒有加”",,echo

"符號的,而在迴圈體內,echo所在行變數
day是必須加上”$”符號的.
程式碼案例:列印當前目錄下f開頭的所有指令碼檔案

#!/bin/sh
for file in $(ls f*.sh)
do
    echo $file
done
exit 0

2.while迴圈

while [ condition ]
do
# code block

done

#! /bin/sh
echo "Enter password"
read trythis

while [ "$trythis" != "secret" ];do
    echo "Sorry,try again"
    read trythis
done
exit 0

3.until迴圈

until [ condition ]
do
# code block
done

區別: while 和 until 的區別在於while 為真時執行,until為假時執行.

4. case 語句

case “$var” in
condition1 )
;;
condition2 )
;;
* )
default statments
;;
esac

#! /bin/sh
echo "Hit a key,then hit return. "
read Keypress
case "$Keypress" in
    [A-Z]) echo "Uppercase letter"
            ;;
    [a-z]) echo "Lowercase letter"
            ;;
    [0-9]) echo "Digit"
            ;;
    *)  echo"Punctuation,whitespace,or other"
            ;;
esac
exit 0

函式

函式的定義方式

function_name(){
statements
}

#! /bin/sh
yes_or_no()
{
    echo "Is your name $* ?"
    while true
    do
        echo -n "Enter yes or no:"
                read x
                case "$x" in
                    y | yes ) return 0 ;;
                    n | no  ) return 1 ;;
                    * ) echo "Answer yes or no" ;;
                esac
    done
}

echo "Original parameters are $*"
if yes_or_no "$1"
then 
    echo "Hi $1,nice name"
else
    echo "Never mind"
fi
exit 0

這裡寫圖片描述


命令

1. break命令

預設情況下,break只跳出一層迴圈.

2. : 命令

冒號(:)命令只是一個空命令.
相當於true的別名. while : 實現無限迴圈
: 結構也會用在變數的條件設定中.
: $ {var:=value}

3. continue命令

使得for,while,untill迴圈跳到下一次迴圈繼續執行.

4. .命令

點(.)命令用於當前shell中的執行命令.

5.echo命令

使用echo命令輸出結尾帶有換行符的的字串.
去掉換行符:
(1)使用 -n
echo -n "string to output"
(2)使用 -e 啟動反斜線轉義字元(\c代表去掉換行符,\t代表製表符,\n代表回車)
echo -e "string to output\c"

6.eval命令

eval命令允許對引數進行求值.
foo=10
x=foo
y='$'$x
echo $y  # 輸出為 $foo
foo=10
x=foo
eval y='$'$x
echo $y # 輸出為10

7.exec命令

兩種不同的用法
(1)將當前shell替換成一個不同的程式.
(2)修改當前檔案描述符

8.exit命令

exit命令使得指令碼以退出碼n結束執行.
在退出碼0代表成功.
退出碼1~125是指令碼程式使用的錯誤程式碼.
退出碼 說明
126 檔案不可執行
127 命令未找到
128以上 出現一個訊號

9.export命令

export:將自定義變數設定為環境變數,這個環境變數可以被當前呼叫的其他指令碼和程式看到.(當前shell中有效)

10.expr命令

 expr命令將它的引數當做一個表示式求值.
expr 2 + 3

11.printf命令

格式化輸出,和C語言中的有點像
$ printf "%s\n" hello
hello
$ printf "%s %d\t%s" "Hi There" 15 people
Hi There 15 people
字元轉換限定符 說明
d 十進位制輸出
c 輸出一個字元
s 輸出一個字串

12.return命令

return命令的作用使函式返回值.

13.set命令

set命令的作用是為shell設定引數變數.
案例程式碼:

#! /bin/sh

echo the date is $(date)
set $(date)
echo $0
echo The year is: $1
echo The month is: $2
echo The day is: $3
exit 2

這裡寫圖片描述

14.shift命令

把所有引數變數左移一個位置,使得$2變成$1,$3變成$2

15.trap命令

trap命令的一種常見用途是在指令碼程式被中斷時完成清理工作.
trap command signal 
兩個引數,一個是接收到指定訊號採取的行動,一個是處理的訊號名.
訊號 說明
HUP(1) 掛起
INT(2) 中斷,Ctrl+C
QUIT(3) 退出,Ctrl+\
ABRT(6) 終止,嚴重執行錯誤傳送
ALRM(14) 報警,處理超時
TERM(15) 終止,系統關機傳送
#! /bin/sh

trap 'rm -f /tmp/my_tmp_file_$$' INT # 捕捉中斷訊號,捕捉到後執行命令,但是程式可以繼續執行.
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$

echo "press interrupt (CTRL-C) to interrupt...."
while [ -f /tmp/my_tmp_file_$$ ];do
    echo File exists
    sleep 1
done
echo The file no longer exists

trap INT  #只捕捉到INT訊號,但是不執行任何命令.採取預設處理方式,立即終止指令碼
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$

echo "presss interrrupt (CTRL-C) to interrrupt..."
while [ -f /tmp/my_tmp_file_$$ ];do
    echo File exists
    sleep 1
done

echo we never get here
exit 0

16.unset命令

unset命令的作用是從環境中刪除變數和函式.
#! /bin/sh

foo="Hello world"
echo $foo

unset foo
echo $foo

說明:和foo= 執行結果一樣,但是並不等同.foo=把foo設定設定為空.但是foo變數仍然存在,使用unset foo 效果是把變數foo從環境中刪除.

參考書籍:
Linux 程式設計

相關文章