1. 程式人生 > >Linux Shell——流程控制

Linux Shell——流程控制

Linux Shell

一. 建立互動式指令碼

使用 echo命令的選項

關於各種命令的使用,可以使用man 命令來檢視命令的詳細用法介紹。例如,我想看下 echo 的用法和各種選項。可以執行 man echo。執行結果如下:

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提供引數時設定,最後打印出來。

執行結果為:

hello3.sh

優化 read 提示的指令碼

在前面的例子中,我們使用了echo -n的方式來阻止資訊換行,其實 read 命令也帶了一個選項來實現相同的功能:

read -p "Enter your name: " name

上面的指令碼中,我們定義了一個變數name用來儲存輸入的內容,如果不定義變數的話,輸入的內容會儲存在REPLY

中。
下面是具體使用的語法:
read -p

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

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

如果我們需要多個表示式,可以使用ANDOR,對應的選項為-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

執行結果如下:

grade

三. 一些注意事項

我們前面已經介紹過 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

執行結果如下:

for loop

在迴圈中,可以使用continuebreak關鍵字,具體用法與其他語言裡是一樣的。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顯示搜尋命令定位到下一個字串

Linuxshell流程控制語句

一、if-else分支結構 if語法格式: if 條件 then 邏輯塊(通常都是些命令) fi 寫成一行:適用於終端寫法 If 條件; then 邏輯 ; fi   If else語法格式: if 條件 then 邏輯塊(通常都是些命令)