什麼是流控制
#!/bin/bash
make /home/wbm/shell/txt
cp *.txt /home/wbm/shell/txt
rm -f *txt
--------------------------------------------
上述腳本會出現問題嗎?
如果目錄創建失敗或成功如何處理
文件拷貝失敗如何處理
test 條件測試
有時判斷字符串是否相等或檢查文件狀態或是數字測試等。
Test命令用於測試字符串,文件狀態和數字
如果test命令中列出的條件成立,test命令就會退出並返回退出狀態碼0
==文件狀態測試
格式 test condition 或 [ condition ]
-d 目錄
-s 文件長度大於0、非空
-f 正規文件
-w 可寫
-L 符號鏈接
-u 文件有suid位設置
-r 可讀
-x 可執行
-z 字符串爲空
hzmct@U-64:/study/linuxtest/day03$ help test
test: test [expr]
Evaluate conditional expression.
Exits with a status of 0 (true) or 1 (false) depending on
the evaluation of EXPR. Expressions may be unary or binary. Unary
expressions are often used to examine the status of a file. There
are string operators and numeric comparison operators as well.
The behavior of test depends on the number of arguments. Read the
bash manual page for the complete specification.
File operators:
-a FILE True if file exists.
-b FILE True if file is block special.
-c FILE True if file is character special.
-d FILE True if file is a directory.
-e FILE True if file exists.
-f FILE True if file exists and is a regular file.
-g FILE True if file is set-group-id.
-h FILE True if file is a symbolic link.
-L FILE True if file is a symbolic link.
-k FILE True if file has its `sticky' bit set.
-p FILE True if file is a named pipe.
-r FILE True if file is readable by you.
-s FILE True if file exists and is not empty.
-S FILE True if file is a socket.
-t FD True if FD is opened on a terminal.
-u FILE True if the file is set-user-id.
-w FILE True if the file is writable by you.
-x FILE True if the file is executable by you.
-O FILE True if the file is effectively owned by you.
-G FILE True if the file is effectively owned by your group.
-N FILE True if the file has been modified since it was last read.
FILE1 -nt FILE2 True if file1 is newer than file2 (according to
modification date).
FILE1 -ot FILE2 True if file1 is older than file2.
FILE1 -ef FILE2 True if file1 is a hard link to file2.
All file operators except -h and -L are acting on the target of a symbolic
link, not on the symlink itself, if FILE is a symbolic link.
String operators:
-z STRING True if string is empty.
-n STRING
STRING True if string is not empty.
STRING1 = STRING2
True if the strings are equal.
STRING1 != STRING2
True if the strings are not equal.
STRING1 < STRING2
True if STRING1 sorts before STRING2 lexicographically.
STRING1 > STRING2
True if STRING1 sorts after STRING2 lexicographically.
Other operators:
-o OPTION True if the shell option OPTION is enabled.
-v VAR True if the shell variable VAR is set
-R VAR True if the shell variable VAR is set and is a name reference.
! EXPR True if expr is false.
EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,
-lt, -le, -gt, or -ge.
Arithmetic binary operators return true if ARG1 is equal, not-equal,
less-than, less-than-or-equal, greater-than, or greater-than-or-equal
than ARG2.
See the bash manual page bash(1) for the handling of parameters (i.e.
missing parameters).
Exit Status:
Returns success if EXPR evaluates to true; fails if EXPR evaluates to
false or an invalid argument is given.
//eg1 使用test指令
$ test -d dir
//顯示前一個命令的運行狀態
$ echo $?
1
//eg2 使用[空格 表達式 空格]
$ [ -w 1 -a -x 2 ]
$ echo $?
1
//eg3 使用腳本
hzmct@U-64:/study/linuxtest/day03$ cat 6testdir.sh
#!/bin/bash
echo "test 命令使用 方法1"
test -d "mulu"
echo $?
echo "test命令使用 方法 2 []"
[ -d "mulu" ]
echo $?
==字符串測試
格式如下:
test "string"
test string_operator "string"
test "string" string_operator "string"
[]方法
[ string_operator string ]
[string string_operator string ]
使用方括號時,要注意在條件兩邊加上空格
測試兩個字符是否相等。退出狀態變量 $?,0表示成功,1表示失敗。
操作數string_operator
= 兩個字符串相等
!= 兩個字符串不等
-z 空串
-n 非空串
eg
hzmct@U-64:~$ echo $chen
hzmct@U-64:~$ [ -z $chen ]
hzmct@U-64:~$ echo $?
0
eg
hzmct@U-64:~$ aa="123"
hzmct@U-64:~$ bb="456"
hzmct@U-64:~$ [ "$aa"="bb" ]
hzmct@U-64:~$ echo $?
0
hzmct@U-64:~$ [ "$aa" = "$bb" ]
hzmct@U-64:~$ echo $?
1
hzmct@U-64:~$ [ "$aa" = "$aa" ]
hzmct@U-64:~$ echo $?
0
==測試數值
格式 測試兩個數值大小
"number" numberic_operator "number"
或者
[ "number" numberic_operator "number" ]
numberic_operator可爲:
-eq 數值相等。
-ne 數值不相等。
-gt 第一個數大於第二個數。
-lt 第一個數小於第二個數。
-le 第一個數小於等於第二個數。
-ge 第一個數大於等於第二個數。
eg:
hzmct@U-64:~$ a1=10
hzmct@U-64:~$ a2=12
hzmct@U-64:~$ [ "$a1" -eq "13" ]
hzmct@U-64:~$ echo $?
1
hzmct@U-64:~$ [ "$a1" -eq "10" ]
hzmct@U-64:~$ echo $?
0
expr數字運算
expr argument operator argument
加法運算:expr 10 + 10
減法運算:expr 20 - 10
加法運算:expr 10 / 5
乘法運算:expr 10 \* 5
eg
hzmct@U-64:~$ expr 10 + 10
20
hzmct@U-64:~$ expr 10+10
10+10
hzmct@U-64:~$ expr 10 * 10
expr: syntax error
hzmct@U-64:~$ expr 10 \* 10
100
hzmct@U-64:~$
if-then
使用if-then 語句
if command
then
command
fi
注意:
bash shell的if語句會運行if後面的那個命令。如果該命令的退出狀態碼是0(該命令成功運行),位於then部分的命令就會被執行。如果該命令的退出狀態碼是其他值, then部分的命令就不會被執行, bash shell會繼續執行腳本中的下一個命令。
fi語句用來表示if-then語句到此結束。
常用的方式
if command; then
command
fi
//例子
hzmct@U-64:/study/linuxtest/day03$ cat 7if.sh
#!/bin/bash
echo "test use 1"
test -w tmp.txt
if [ $? -eq "0" ];then
echo -e "success\n"
else
echo -e "not success\n"
fi
echo $?
echo "test use 2 [] begin"
[ -w tmp.txt ]
echo $?
if then else
語法1
if command
then
command
else
command
fi
eg
hzmct@U-64:/study/linuxtest/day03$ cat 8ifelse.sh
#!/bin/bash
if [ "13" -lt "12" ]
then
echo "yes 13 is less than 12"
else
echo "NO"
fi
if嵌套
if command1
then
commands
elif commmand2
then
commands
fi
eg:檢查文件是否爲空,若是空文件刪除
#!/bin/bash
echo -n "Enter your filename:"
read myfile
if [ -e $myfile ]; then
if [ -s $myfile ]; then
echo "$myfile exist and size greater than zero"
echo "will not remove this file"
else
echo "$myfile exist but size is zero"
echo "delete empty file ......"
rm $myfile
fi
else
echo "file no exist"
fi
hzmct@U-64:/study/linuxtest/day03$ ./9ifif.sh
Enter your filename:1
file no exist
hzmct@U-64:/study/linuxtest/day03$ touch 1
hzmct@U-64:/study/linuxtest/day03$ ./9ifif.sh
Enter your filename:1
1 exist but size is zero
delete empty file ......
if-then的高級特性
bash shell提供了兩項可在if-then語句中使用的高級特性:
用於數學表達式的雙括號
用於高級字符串處理功能的雙方括號
==雙括號
表達式
(( expression))
expression可以是任意的數學賦值或比較表達式。除了test命令使用的標準數學運算符,
表12-4列出了雙括號命令中會用到的其他運算符
val++ 後增
val-- 後減
++val 先增
--val 先減
! 邏輯求反
~ 位求反
** 冪運算
<< 左位移
>> 右位移
& 位布爾和
| 位布爾或
&& 邏輯和
|| 邏輯或
hzmct@U-64:~$ echo $((10 ** 2))
100
hzmct@U-64:/study/linuxtest/day03$ cat 10ifshuangkuohao.sh
var1=10
if (( $var1 ** 2 > 90)); then
(( var2 = $var1 ** 2))
echo "The square of $var1 is $var2"
fi
==雙方括號
雙方括號命令提供了針對字符串比較的高級特性。雙方括號命令的格式如下:
[[ expression ]]
雙方括號裏的expression使用了test命令中採用的標準字符串比較。但它提供了test命
令未提供的另一個特性——模式匹配(pattern matching)
說明 :雙方括號在bash shell中工作良好。不過要小心,不是所有的shell都支持雙方括號。
eg:
hzmct@U-64:/study/linuxtest/day03$ cat 11ifshuangfangkuohao.sh
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry, I do not know you"
fi
hzmct@U-64:/study/linuxtest/day03$ USER="rich"
hzmct@U-64:/study/linuxtest/day03$ ./11ifshuangfangkuohao.sh
Hello rich
使用了雙等號(==)。雙等號將右邊的字符串(r*)視爲一個模式,
並應用模式匹配規則。雙方括號命令$USER環境變量進行匹配,看它是否以字母r開頭。如果是
的話,比較通過, shell會執行then部分的命令。
case
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
case命令會將指定的變量與不同模式進行比較。如果變量和模式是匹配的,那麼shell會執行
爲該模式指定的命令。可以通過豎線操作符在一行中分隔出多個模式模式。星號會捕獲所有與已
知模式不匹配的值。
hzmct@U-64:/study/linuxtest/day03$ cat 12case.sh
#!/bin/bash
if [ $USER = "rich" ];then
echo "welcom $USER"
echo "please enjoy your visit"
elif [ $USER = "barbara" ];then
echo "welcom $USER"
echo "please enjoy your visit"
elif [ $USER = "testing" ];then
echo "welcom $USER"
echo "special testing account"
elif [ $USER = "jessica" ];then
echo "Do not forget to logout when you're done"
fi
case $USER in
rich | barbara)
echo "welcom, $USER";;
testing)
echo "special testing account";;
jessica)
echo "do not forget to log off when you are done";;
*)
echo "sorry, you are not allowed here";;
esac
case多選擇語句格式:
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
1)case取值後面必須爲單詞in;每一模式必須以右括號結束。
2)取值可以爲變量或常數。匹配發現取值符合某一模式後,其後的所有命令開始執行,直到;;
3)模式匹配*表示任意字符; ?表示任意單字符; [..]表示類或範圍中任意字符
eg:
hzmct@U-64:/study/linuxtest/day03$ cat 13case.sh
#!/bin/bash
echo -n "enter a number from 1 to 3:"
read num
case $num in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
y|Y)
echo "you select y/Y"
;;
*)
echo " `basename $0` :this is not between 1 and 3">&2
echo " $0 :this is not between 1 and 3">&2
exit;
;;
esac
循環命令 for
語法格式:
for循環一般格式
for 變量名 in 列表
do
命令1
命令2
done
1 當變量值在列表裏,for循環即執行依次所有命令,使用變量名訪問列表中取值。
2 命令可爲任何有效的shell命令和語句。變量名爲任意單詞。
3 in列表用法是可選擇,如果不用它,for循環使用命令行的位置參數。
4 in列表可以包含替換、字符串和文件名
eg:
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
for i in aaa bbb ccc
do
echo $i
done
for loop in `cat myfile`
do
echo $loop
done
for test in I don\'t know if "this'll" work in "New york"
do
echo "word:$test"
done
hzmct@U-64:/study/linuxtest/day03$ ./14for.sh
1
2
3
4
5
aaa
bbb
ccc
11
22
33
word:I
word:don't
word:know
word:if
word:this'll
word:work
word:in
word:New york