Linux Shell——流程控制
一. 建立互動式指令碼
使用 echo命令的選項
關於各種命令的使用,可以使用man 命令
來檢視命令的詳細用法介紹。例如,我想看下 echo 的用法和各種選項。可以執行 man echo
。執行結果如下:
如果單獨執行 echo 命令,就會打印出一個空白行。
預設情況下,echo 都會換行,如果不想換行的話,可以使用下面兩種方式的一種。
echo -n "Which directory do you want to use? "
echo -e "Which directory do you want to use? \c"
使用 read 命令
如果我們需要讀入使用者輸入的引數時,可以使用 read 命令,當然還可以從檔案系統等讀入資訊。
我們建立一個新的指令碼檔案 hello3.sh。
#!/bin/bash
echo -n "Hello I $(basename $0) may I ask your name: "
read
echo "Hello $REPLY"
exit 0
執行此指令碼時,首先提示需要輸入,然後輸入的內容,REPLY
當沒有給read
提供引數時設定,最後打印出來。
執行結果為:
優化 read 提示的指令碼
在前面的例子中,我們使用了echo -n
的方式來阻止資訊換行,其實 read 命令也帶了一個選項來實現相同的功能:
read -p "Enter your name: " name
上面的指令碼中,我們定義了一個變數name
用來儲存輸入的內容,如果不定義變數的話,輸入的內容會儲存在REPLY
下面是具體使用的語法:
hello3.sh的指令碼可以改成如下:
#!/bin/bash
read -p "May I ask your name: " name
echo "Hello $name"
exit 0
限制輸入內容的個數
我們還可以使用 read命令的-n 選項,此選項後面需要接一個數字,可以限制輸入內容的個數。
#!/bin/bash
read -p "May I ask your name: " name
echo "Hello $name"
read -n1 -p "Press any key to exit"
echo
exit 0
控制輸入內容的可見性
目前,我們輸入的內容都是可見的,但有些敏感的資料,如密碼,信用卡號等資訊,輸入時並不想可見。那麼可以使用read -s
這時再輸入時,就有一個鑰匙的標識,而且輸入時不可見。
例項演示
現在有一個小程式,要求把指定字尾的檔案備份到指定的目錄下,程式碼如下:
#!/bin/bash
# Script to prompt to back up files and location
# The files will be search on from the user's home
# directory and can only be backed up to a directory within $HOME
read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name
# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name
# The find command will copy files the match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the back directory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o \
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
exit 0
二. 條件判斷語句
使用test 內建函式
test命令是 shell 環境中用於測試條件表示式的工具。
它的返回值可以是 true,false,0或1。基本語法為:
test EXPRESSION
如果我們需要多個表示式,可以使用AND
,OR
,對應的選項為-a
,-o
。
test EXPRESSION -a EXPRESSION
test EXPRESSION -o EXPRESSION
其實,在實際應用中,test 有種非常簡潔的方式,就是被中括號包含的條件表示式。這種方式更加常用。語法如下:
[ EXPRESION ]
test 的用法很多,例如,可以比較兩個字串是否相等:
[ $USER = root ]
我們還可以test 的選項來判斷一個字串的長度是否為0。
[ -z $1 ]
上面的程式碼的含義是,如果沒有引數輸入的話,返回 true。
test 還可以用來比較數字的大小。例如:
[ $# -gt 0 ]
除此而外,還可以判斷檔案的型別。例如,我們想查詢型別為符號連結的檔案,然後刪除。可以使用如下指令碼:
# [ -h $HOME/bin ] &&rm $HOME/bin
其他常用的選項如下:
- -d:檔案是否為目錄
- -e:檔案是否存在
- -x:檔案是否可以執行
- -f:檔案是否為常規檔案
- -r:檔案是否可讀
- -p:檔案是否為命名管道
- -b:檔案是否為塊裝置檔案
- -c:檔案是否為字元裝置檔案
使用 if 條件判斷語句
if 語句的基本格式為:
if conditon ; then
statement 1
statement 2
fi
我們可以看一個具體的例子:
#!/bin/bash
if [ $# -lt 1 ] ; then
echo "Usage: $0 <name>"
exit 1
fi
echo "Hello $1"
exit 0
在執行此指令碼時,如果沒有輸入引數,則提示正確的使用方法,非正常退出;否則,列印輸入的引數,程式正常退出。
if 語句還可以使用 else 條件分支。具體的語法為:
if conditon ; then
statement
else
statement
fi
我們新建一個指令碼檔案 hello6.sh,來展示 if else 的用法。
#!/bin/bash
if [ $# -lt 1 ] ; then
read -p "Enter a name: "
name=$REPLY
else
name=$1
fi
echo "Hello $name"
exit 0
當沒有輸入引數時,程式提示需要輸入一個 name;如果輸入了的話,就會打印出來。
最後一種 if 的情況,也是最完整的 if 條件語句。語法如下;
if condition; then
statement
elif condition; then
statement
else
statement
fi
再舉個例子,新建指令碼 backup2.sh,我們使用 tar 命令來備份壓縮指定的目錄,根據輸入的引數“H”,“M”,“L”,可以執行不同的壓縮級別。
如果輸入的引數為“H”,則使用 bzip2的壓縮方式;
如果輸入的引數為“M”,則使用 gzip 的壓縮方式;
如果輸入的引數為“L”,則使用 tar 命令對檔案打包,不壓縮。
#!/bin/bash
# this sciprt dirs’ location are defualt under $HOME
read -p "Choose H, M or L compression " file_compression
read -p "Which directory do you want to backup to " dir_name
read -p "Which directory do you went to backup: " tobe_backup_name
# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name
backup_dir=$HOME/$dir_name
tar_l="-cvf $backup_dir/b.tar $HOME/$tobe_backup_name"
tar_m="-czvf $backup_dir/b.tar.gz $HOME/$tobe_backup_name"
tar_h="-cjvf $backup_dir/b.tar.bzip2 $HOME/$tobe_backup_name"
if [ $file_compression = "L" ] ; then
tar_opt=$tar_l
elif [ $file_compression = "M" ]; then
tar_opt=$tar_m
else
tar_opt=$tar_h
fi
tar $tar_opt
exit 0
使用 case 選擇語句
如果 if else 分支太多的話,可以考慮使用 case 語句,case 語句提供了更加簡潔的機制。
case 語句的語法結構為:
case expression in
case1)
statement1
statement2
;;
case2)
statement1
statement2
;;
*)
statement1
;;
esac
還是舉個簡單的例子,新建指令碼檔案 grade.sh。
#!/bin/bash
# Script to evaluate grades
# Usage: grade.sh studentName grade
if [ ! $# -eq2 ] ; then
echo "You must provide <studentName> <grade>
exit 2
fi
case $2 in
[A-C]|[a-c])
echo "$1 is a star pupil"
;;
[Dd])
echo "$1 needs to try a little harder!"
;;
[E-F]|[e-f])
echo "$1 could do a lot better next year"
;;
*)
echo "Grade could not be evaluated for $1"
esac
exit 0
執行結果如下:
三. 一些注意事項
我們前面已經介紹過 test 內建命令用來判斷條件語句,但通常我們會推薦使用[]來替代 test 命令。例如:
[ -f /etc/hosts -a -r /etc/hosts ]
但這裡面有個問題,例如,下面的指令碼中,檔名中有空格,我們都知道,空格在命令列中有特殊的用處,用來分割命令選項和引數等。下面的程式碼會報錯。
FILE="my file"
[ -f $FILE -a -r $FILE ] && cat $FILE
報錯資訊為“too many arguments”,原因是程式把帶有空格的檔名解析成了兩部分。
而這時,我們需要把變數用雙引號包含起來,
FILE="my file"
[ -f "$FILE" -a -r "$FILE" ] && cat "$FILE"
那有沒有好的辦法可以不使用雙引號呢?當然有的,那就是使用“[[”關鍵字。
“[[”並不是所有的 shell 都支援,它不相容Bourne Shell。我們可以用 type 命令來檢視它的型別。
上面的指令碼中的[]內的雙引號就可以不用了,但要注意的是 cat 裡的雙引號還是要有的。
FILE="my file"
[[ -f $FILE && -r $FILE ]] && cat "$FILE"
“[[”還有其他高階的功能:
1. 模式匹配
例如,我們需要判斷 Perl 指令碼,然後做其他的操作,那麼就可以這樣寫:
[[ $FILE = *.pl ]] && cp "$FILE" scripts/
2. 正則表示式
我們可以使用“=~”來匹配正則表示式。我們可以用正則表示式重寫上面的指令碼。
$ [[ $FILE =~ \.pl$ ]] &&cp "$FILE" scripts/
我們還可以使用“(())”運算子來做一些簡單的運算。
1. 簡單的數學運算
我們可以使用“((”做一些簡單的數學運算,它可以替代 let 這個內建命令。下面兩行的程式碼執行結果是一樣的。
a=(( 2 + 3 ))
let a=2+3
2. 用在迴圈累加或累減中
這種方式更加常用,
COUNT=1
(( COUNT++ ))
echo $COUNT
3. 用於運算檢查中
我們也可以把“((”用在 test 判斷條件中,我們可以是用“>” 符號,來替代“-gt”。
(( COUNT > 1 )) && echo "Count is greater than 1"
四. 迭代迴圈
迴圈語句是任何一門語言都不能缺失的部分。shell 裡也是一樣,只是語法不太一樣。如果學過其他的程式語言,就很容易掌握。
1. for 迴圈
for 迴圈的語法疾結構為:
for f in * ; do
statement "$f"
done
這裡的 f 就是迭代的元素,* 可以是一個數組或是 list,也可以是命令管道。
還有另外一種寫法:
for f in *
do
statement "$f"
done
可以根據自己的喜好選擇一種寫法。
新建一個指令碼檔案,打印出所有輸入的引數:
#!/bin/bash
echo "You are using $(basename $0)"
for n in $*
do
echo "Hello $n"
done
exit 0
執行結果如下:
在迴圈中,可以使用continue
和break
關鍵字,具體用法與其他語言裡是一樣的。continue
表示在迴圈體內,跳過當前迴圈,執行下次的迴圈;而break
表示退出整個迴圈,後面的迴圈和程式碼不再執行。
看具體看例子。
$ for f in * ; do
[ -d "$f" ] || continue
chmod 3777 "$f"
done
如果是目錄,新增許可權;如果不是,跳過當前迴圈,continue 後面程式碼不再執行,而是直接執行下次迴圈。
$ for f in * ; do
[ -d "$f" ] && break
done
echo "We have found a directory $f"
上面的指令碼,在迴圈中一旦發現目錄,則立即停止迴圈並退出。
2. while 迴圈
while 迴圈可以說是 for 迴圈的一個變體,只要特定條件為真,while
語句就會執行。具體看例子,
COUNT=10
while (( COUNT >= 0 )) ; do
echo -e "$COUNT \c"
(( COUNT-- ))
done ;
echo
3. until 迴圈
until
迴圈與while
語句的功能正好相反:只要特定條件為假,它就重複。下面是一個與前面的 while
迴圈具有同等功能的 until
迴圈。
COUNT=10
until (( COUNT < 0 )) ; do
echo -e "$COUNT \c"
(( COUNT-- ))
done ;
echo
4. 例項練習
現在,我們做一個使用者選擇介面,這樣,根據提示輸入不同的引數來執行不同的功能,這裡我們需要用到while
迴圈,和前面講過的case
條件選擇。
#!/bin/bash
while true ; do
clear
echo "Choose an item: a, b or c"
echo "a: Backup"
echo "b: Display Calendar"
echo "c: Exit"
read -sn1
case "$REPLY" in
a) tar -czvf $HOME/backup.tgz ${HOME}/JavaSource;;
b) cal;;
c) exit 0;;
esac
read -n1 -p "Press andy key to continue"
done
根據提示,如果輸入 a 的話,則把 home 目錄下的 JavaSource 目錄壓縮打包。
輸入b,顯示當前月份。
輸入c,程式退出。
相關推薦
[轉]linux shell 流程控制(條件if,迴圈【for,while】,選擇【case】語句例項
linux shell有一套自己的流程控制語句,其中包括條件語句(if),迴圈語句(for,while),選擇語句(case)。下面我將通過例子介紹下,各個語句使用方法。 一、shell條件語句(if用法) if語句結構[if/then/elif/else/fi] if 條件測試語句
Linux Shell——流程控制
一. 建立互動式指令碼 使用 echo命令的選項 關於各種命令的使用,可以使用man 命令來檢視命令的詳細用法介紹。例如,我想看下 echo 的用法和各種選項。可以執行 man echo。執行結果如下: 如果單獨執行 echo 命令,就會打印出一個空白行。 預設情況下,echo 都會換行,如果不想換行的話
shell--8、Shell 流程控制
shell 流程控制和Java、PHP等語言不一樣,sh的流程控制不可為空,如(以下為PHP流程控制寫法):<?php if (isset($_GET["q"])) { search(q); } else { // 不做任何事情 }在sh/bash裏可不能這麽寫,如果else分支沒有語句
shell 流程控制語句
pan oot 示例 strong 更多 -o 一個 post 文件 一、if 語法格式:if test -d $arg then ... else ... fi 變量測試語句可以用 [ ] 簡化。例:test -d $arg 等價於 [ -d $arg ]。( 註意:"空
008-Shell 流程控制
str 有一點 代碼 while 循環 功能 語言 命令提示符 i++ 等於 一、if else 1.1、if if 語句語法格式: if condition then command1 command2 ... com
linux shell流程例子
\n param parameter ptime break 數字 IT root baidu #!/bin/bash read -p "input a dight:"echo $REPLY DATE=`date`echo "DATE is ${DATE}" USERS=`
12-shell 流程控制
item 過程 num case語句 一行 個數字 無限 進行 語句 在sh/bash裏可不能這麽寫,如果else分支沒有語句執行,就不要寫這個else。 if else ifif 語句語法格式: if condition then command1
shell流程控制語句 case
不常用 多個 流程 shell流程控制 ase 讀取 ext ffffff 提示符 linux的shell前前後後學了好幾遍了奈何記性不好,總是忘了,追主要的原因可能是不常用的原因吧!case開頭 esac結尾下面是結果輸入法不對 輸入的符號就不對,剛開始總錯,後來切換了
shell ,流程控制
#如果ps -ef | grep -c "ssh"的結果大於一行,列印true if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi #判斷兩個變數是否相等 a=10 b=20 if [ $a == $b
shell流程控制
shell流程控制 if 判斷 基本語法 if [ 條件判斷式 ];then 程式 fi或者 if [ 條件判斷式 ] then 程式 elif [條件判斷式] then 程式 fi 注意事項:(1)[ 條件判斷式 ],中括號和條件判斷式之間必須有空格 (2) 推薦使用第二種方式
Shell程式設計七-Shell 流程控制
Shell 流程控制 一、if語句 if 語句語法格式: if condition then command1 command2 ... commandN 
學習筆記 shell流程控制語句 if 和 for
if條件測試語句 使用單分支的if條件語句來判斷/media/cdrom檔案是否存在,若存在就結束條件判斷和整個Shell指令碼,反之則去建立這個目錄: [[email protected] ~]# vim 1.sh #!/bin/bash DIR="
Shell流程控制語句
在Linux Shell程式設計中,if、for、while、case等條件流程控制語句用的非常多,把這些學好,對提升指令碼的功力有非常大的幫助。下面將逐個來講解具體的用法: If條件判斷語句 I
shell--流程控制
l if語句 bash流程控制不可為空,else分支沒有語句執行,就不寫else if condition1 then command1 elif condition2 then command2 else commandN fi l for
Linux shell腳本流程控制
linux 循環 選擇 博主搬家至51CTO,初來乍到,請多指教。此次我們來通過實例解析Linux shell腳本流程控制Linux shell腳本流程控制可分為三類:順序執行,條件選擇執行,循環執行順序執行:簡單理解就是逐行執行腳本內容,逐行解讀,逐行執行。(此處不做實例解析)條件選擇執行:可以
1 Linux shell 編程(七):流程控制語句
shell if else Linux 流程控制語句 在shell中如果在終端輸入多個命令,如果以&分隔則將命令放入後臺執行,如果以;分隔,則表示一個命令集合。shell允許使用邏輯操作符&&和||來作為命令分隔符,他們分別時AND和OR. && 如果前
Linux Bash Shell學習(十二) 流程控制——select
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
linux Vim編輯器、shell指令碼、流程控制語句和計劃任務
本章主要講解shell指令碼,vim編輯器 1. 強制儲存退出 wq! 2. 查詢主機名稱 hostname 3. 在vim中常用的命令 dd刪除游標所在行;5dd刪除自游標所在行開始往下數五行;yy複製游標所在行;5yy複製自游標所在行開始往下數5行內容;n顯示搜尋命令定位到下一個字串
Linux之shell的流程控制語句
一、if-else分支結構 if語法格式: if 條件 then 邏輯塊(通常都是些命令) fi 寫成一行:適用於終端寫法 If 條件; then 邏輯 ; fi If else語法格式: if 條件 then 邏輯塊(通常都是些命令)