Shell程式設計 筆記
阿新 • • 發佈:2018-11-19
shell程式設計就是將shell命令寫在一個.sh檔案裡面,類似批處理檔案,一次執行多條語句
使用readonly關鍵字可以建立只讀變數,不能修改
readonly mm="ss"
#這條語句報錯
mm='ss'
unset 可以刪除已經宣告的變數
mm ='mm'
unset mm
#這條語句沒有輸出
echo $mm
shell迴圈,以下程式碼實現迴圈
for skill in Ada Coffe Action Java
do
echo "I am good at ${skill}Script"
done
#輸出
I am good at AdaScript
I am good at CoffeScript
I am good at ActionScript
I am good at JavaScript
有一些變數是特殊變數,代表特殊的含義
變數名 | 含義 |
---|---|
$0 | 當前指令碼的檔名 |
$n | 傳遞給指令碼或函式的引數。n 是一個數字,表示第幾個引數。例如,第一個引數是$1,第二個引數是$2。 |
$# | 傳遞給指令碼或函式的引數個數。 |
$* | 傳遞給指令碼或函式的所有引數。 |
$@ | 傳遞給指令碼或函式的所有引數。被雙引號(” “)包含時,與$* 稍有不同,下面將會講到。 |
$? | 上個命令的退出狀態,或函式的返回值。 |
$$ | 當前Shell程序ID。對於 Shell 指令碼,就是這些指令碼所在的程序ID。 |
shell指令碼引數,下例實現傳遞引數並輸出
echo $1
echo $2
#執行 ./test.sh run log
#輸出
run
log
$* 和$@的區別
都是表示輸入引數的集合,$* 和 $@沒有區別,”$
#!/bin/bash
echo "\$*=" $*
echo "\"\$*\"=" "$*"
echo "\[email protected]=" [email protected]
echo "\"\[email protected]\"=" "[email protected]"
echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \[email protected]"
for var in [email protected]
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\[email protected]\""
for var in "[email protected]"
do
echo "$var"
done
#執行./test.sh "a" "b" "c" "d",
#輸出
$*= a b c d
"$*"= a b c d
[email protected]= a b c d
"[email protected]"= a b c d
print each param from $*
a
b
c
d
print each param from [email protected]
a
b
c
d
print each param from "$*"
a b c d
print each param from "[email protected]"
a
b
c
d
命令替換
命令替換指的是將命令的輸出或者返回暫存在變數中,接下來通過輸出變數的形式,注意與閉包不同的是這個輸出會馬上獲得,不是接下來呼叫的時候才執行,示例如下:
a='12'
b=`echo $a`
a='34'
echo $b
#執行./test.sh
#輸出12
變數替換
變數 | 替換 |
---|---|
${var} | 變數本來的值 |
${var:-word} | 如果變數 var 為空或已被刪除(unset),那麼返回 word,但不改變 var 的值。 |
${var:=word} | 如果變數 var 為空或已被刪除(unset),那麼返回 word,並將 var 的值設定為 word。 |
${var:?message} | 如果變數 var 為空或已被刪除(unset),那麼將訊息 message 送到標準錯誤輸出,可以用來檢測變數 var 是否可以被正常賦值。若此替換出現在Shell指令碼中,那麼指令碼將停止執行。 |
${var:+word} | 如果變數 var 被定義,那麼返回 word,但不改變 var 的值。 |
運算子
shell 預設沒有數學運算子,可以使用expr來做數學運算
#!/bin/sh
a=10
b=20
v=`expr $a + $b`
echo "a+b:$v"
v=`expr $a - $b`
echo "a-b:$v"
v=`expr $a \* $b`
echo "a\*b:$v"
v=`expr $b / $a`
echo "b/a:$v"
v=`expr $b % $a`
echo "b%a:$v"
if [ $a == $b ]
then
echo "a is euqal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi
#輸出
a+b:30
a-b:-10
a\*b:200
b/a:2
b%a:0
運算子之間必須要有空格,可能是因為運算子是用函式實現的,賦值的=和變數之間不能有空格,有了空格就會被當成命令而不是變數,從而顯示沒有這個命令
shell單引號裡面不能引用變數,雙引號可以,這裡也實現了字串的拼接,
your_name='liuchenfei'
stra='single quote $your_name'
strb="double quote $your_name"
echo $stra
echo $strb
#輸出
single quote $your_name
double quote liuchenfei
${#str}可以計算字串的長度
your_name="liuchenfei"
echo ${#your_name}
#輸出
10
${str:m:n}提取字串m-n個字元
your_name="liuchenfei"
echo ${your_name:1:4}
#輸出
iuch
expr查詢字串
your_name="liuchenfei"
echo `expr index $liuchenfei chen`
#輸出
4
定義陣列
array_name=(value0,value1,…………)
或
array_name[0]=value0…………
訪問陣列
echo ${array_name[n]}#訪問第n個元素
echo ${array_name[*]}#訪問全部元素,@和*在這裡相同
${#list}和${list:m:n}也可以對陣列求長度和切片
echo “ff” > myfile 將輸出重定向到檔案myfile中,終端不再顯示輸出
可以使用printf 函式類似c語言printf 輸出
in="integer"
printf "%d is %s \n" 1 \$in
#輸出
1 is integer
if else 語句
shell if else語句的特點是在if下一行要加上then,結尾要加上fi
格式如下:
#if
if [ 條件 ]
then
語句體
fi
#if else
if [ 條件 ]
then
語句體
else
語句體
fi
#if elif
if [條件]
then
語句
elif [條件]
then
語句
fi
比較表示式
表示式 | 含義 | 備註 |
---|---|---|
-eq | 檢測兩個數是否相等,相等返回 true。 | [ $a -eq $b ] 返回 true。 |
-ne | 檢測兩個數是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 檢測左邊的數是否大於右邊的,如果是,則返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 檢測左邊的數是否小於右邊的,如果是,則返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 檢測左邊的數是否大等於右邊的,如果是,則返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 | [ $a -le $b ] 返回 true。 |
邏輯表示式
表示式 | 含義 |
---|---|
! | 非 |
-o | 或 |
-a | 與 |
多分支結構
類似switch-case的結構
read a
case a in
1) echo "this is 1"
;;
2) echo "this is 2"
;;
*) echo "this is $a"
;;
esac
#執行
./sw.sh
1
#輸出
this is 1
for迴圈
for val in list
do
語句
done
while迴圈
while [條件]
do
語句
done
until 迴圈
#條件成立的時候還執行一次
until [條件]
do
語句
done