Linux Shell簡明教程(二)

系列文章首發平臺爲果凍想個人博客。果凍想,是一個原創技術文章分享網站。在這裏果凍會分享他的技術心得,技術得失,技術人生。我在果凍想等待你,也希望你能和我分享你的技術得與失,期待。

果凍想-一個原創技術文章分享網站

一篇遲到的總結

本來說好在總結完第一篇《Linux Shell簡明教程(一)》,就接着總結這篇的,但是中間出了很多事情,一直沒有進行總結,這篇文章的大綱都寫好了,就是一直沒有去完善那些細節部分。今天終於有時間了,就開始陸續的完成這篇文章吧。

這篇文章主要還是對Linux Shell中的一些常用命令進行總結,這裏將要總結的命令在你日後的工作中,或者閱讀別人的代碼中,都會或多或少的使用。不管用不用吧,至少能學點東西,廢話少說,來吧。

break命令

就像其它語言中的一樣,break的意思同它們都一樣,就是跳出while或者for等循環,例如以下代碼:

#!/bin/bash 

while : 
do  
    echo "Please input your choose:"
    read input

    case "$input" in
        1 ) echo "Your input number is 1.";;
        2 ) echo "Your input number is 2.";;
        3 ) echo "Your input number is 3.";;
        4 ) echo "Your input number is 4.";;
        5 ) echo "It's over."
            break #這裏跳出while循環
           ;;
        * ) echo "Your input number is too larger.";;
    esac
done
exit 0

請注意,在case語句中,執行完每個分支以後,就會結束,並不會像C++那樣,還會依次執行它下面的分支語句。

: 命令

Shell命令總是有一些奇怪的命令符,比如之前看到的“[”;這裏又來了一個。你沒有看錯,“:”這貨也是有特殊含義的。

看上面break命令的示例代碼,看到while後面跟着的“:”了麼?它就是這麼用的,它是true的別名,就是表示真,再例如以下代碼:

#!/bin/bash

if : # 有木有看到
then
    echo ": is true"
fi

if true 
then
    echo "true is true"
fi

就是這樣的了,由於“:”是內置命令,所以它的運行速度比true快。

continue命令

break和continue命令,和其它語言中的意思是一樣的。break是結束整個循環動作;而continue是結束這一個單次循環,而整個循環動作不會終止。這裏就不舉例說明了。

eval命令

eval命令允許對參數進行求值,它的格式如下:

eval [arg ...]

把參數當做一個Shell命令來執行。這是對eval最簡單的解釋了。eval命令會將參數連接爲一個整的字符串,然後將這個字符串作爲一個新的Shell輸入進行執行。

當我們將一些字符串作爲eval的參數時,Shell在執行整個eval命令時,它會對eval命令的參數進行兩次掃描。例如以下示例代碼:

#!/bin/bash

a=10
x=a

eval y='$'$x
echo $y

exit 0

在eval執行的過程中,先對y='$'$x進行第一次掃描,得到y=$a;然後再進行第二次掃描,也就是執行y=$a,得到了y=10;當執行echo $y的時候,就輸出結果10。

exit n命令

exit命令使腳本以退出碼n結束運行。如果允許自己的腳本程序在退出時不指定一個退出狀態,那麼該腳本中最後一條被執行命令的狀態將被用作爲返回值。在腳本程序中提供一個退出碼總是一個良好的習慣。

在Shell腳本編程中,退出碼0表示成功,退出碼1~125是腳本程序可以使用的錯誤代碼。其餘數字具有保留的含義,具體請Google。

expr命令

expr命令是一個手工命令行計數器,用於在UNIX/LINUX下求表達式變量的值,一般用於整數值,也可用於字符串。以下通過實際的簡單代碼來看看expr的使用。

#!/bin/bash
# 獲取字符串的長度
expr length "http://www.jellythink.com"

#截取子串
expr substr "http://www.jellythink.com" 12 21

#整數運算

var=`expr 10 / 2`
echo $var

var=$(expr 10 \* 2)
echo $var

exit 0

在上面的腳本中,使用了反引號(“),使用了該引號,就可以使expr的執行結果賦值給var變量,當然了,我們在腳本中也看到了$()來替換反引號的用法,這都是可以的。

expr命令的功能比較簡單、單一,但是很強大。但是需要注意的是,在進行乘法運算時,如果寫成:

expr 10 * 2

這樣就會報錯,這是由於*號在Shell有特殊意義,我們需要加上轉義字符\

printf命令

printf命令就是帶有format功能的echo。它可以對輸出的內容進行格式化,就好比C語言中的printf是一樣的。比如以下示例代碼:

#!/bin/bash

printf "%s\n" http://www.jellythink.com
printf "%c + %s = %s\n" 1 10 11
字符轉換限定符 說明
d 輸出一個十進制數字
c 輸出一個字符
s 輸出一個字符串
% 輸出一個%字符

return命令

return命令的作用是使函數返回。return命令有一個數值參數,這個參數在調用該函數的腳本程序中被看做是該函數的返回值;如果沒有指定參數,return命令默認返回最後一條命令的退出碼。

set命令

set命令作用主要是顯示系統中已經存在的shell變量,以及爲已經存在的shell變量設定新的值。使用set更改shell特性時,符號”+”和”-“的作用分別是打開和關閉指定的模式。set命令不能夠定義新的shell變量。如果要定義新的變量,可以使用declare命令以變量名=值的格式進行定義即可。

當使用set命令不帶任何參數時,它會輸出系統中已經存在的所有Shell變量;我們可以使用set設置我們本地的Shell變量,當退出Shell時,這些本地的Shell變量就會失效,如果需要永久的保存這些Shell變量,則需要寫入配置文件中。

shift命令

shift命令把所有參數變量左移一個位置,使2 1,3 2,以此類推;而2 1的位置之後,原來$1的值就會被丟棄。

在掃描處理腳本程序的時候,經常要用到shift命令。如果你的腳本命令程序需要10個或10個以上的參數,我們就需要使用shift命令來訪問第十個及其後面的參數。

trap命令

trap命令用於指定在接收到信號後將要採取的行動。trap命令的一種常見用途是在腳本程序中斷時完成清理工作。在Linux系統中定義了許多信號,它們被定在頭文件signal.h中,在使用信號名時需要省略SIG前綴。我們在命令行下可以使用trap -l查看所有的信號量定義,及其對應的數字。

trap有兩個參數,第一個參數是接收到指定信號時將要採取的行動,第二個參數是要處理的信號名。格式如下:

trap command signal

下面就通過一個簡單的實例來學習一下trap命令的使用,代碼如下:

# !/bin/bash

# 當按下ctrl+c觸發中斷信號以後,就刪除臨時文件
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 file is no longer exists

#取消INT信號對應的處理
trap 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 I never get here
exit 0

當按下ctrl + c組合鍵時,就會觸發INT中斷,然後就會刪除創建的臨時文件。

unset命令

unset命令的作用是從環境中刪除變量或函數,這個命令不能刪除shell本身定義的只讀變量。

命令的執行

我們在編寫腳本的時候,經常需要捕獲一條命令的執行結果,然後將這個結果保存在另一個變量中。在總結expr命令時,說到可以使用“符號。是的,不錯,使用反引號確實可以完成,但是我們更建議使用$(command)來完成這項工作。

$(command)的結果就是其中命令的輸出。注意,這不是該命令的退出狀態,而是它的字符串形式的輸出結果。比如以下腳本代碼:

x=$(date)
echo $x

我們將date命令的輸出結果保存在x變量中,然後就可以輸出對應的結果。

這種把命令的執行結果存儲到變量中的功能是巨大的,它使得在腳本程序中使用現有命令並捕獲其輸出變得很容易;這樣我們可以配合xargs命令,將標準輸出作爲另一個程序的參數。

算術擴展

在上面總結了expr命令可以完成簡單的算術運算。但是這個命令執行起來是非常的慢得,因爲它需要調用一個新的shell來處理expr命令。

一種更好的方式是使用$((...))擴展,把我們準備求值的表達式放在$((...))中就能夠更有效地完成簡單的算術運算。例如以下代碼:

# !/bin/bash

x=0
while [ "$x" -ne 10 ]
do
    echo $x
    x=$(($x+1))
done

exit 0

在使用的時候一定要記住了,是雙括號。

參數擴展

首先看一段簡單的代碼:

# !/bin/bash

for ((i=0;i<=10;++i))
do
    echo $i_JellyThink
done
exit 0

我們期望得到的是0_JellyThink、1_JellyThink…等值,但是實際上是什麼也不會得到。這是爲什麼呢?

問題出在於Shell試圖替換變量$i_JellyThink$i的值的時候,理解爲替換$i_JellyThink的值,而實際上不存在$i_JellyThink這個變量,所以就被替換成空值了。在實際寫代碼時,爲了保護變量名中類似於$i部分的擴展,我們需要把i放在花括號中,如下:

echo ${i}_JellyThink

這樣就不會出現問題了,對於參數擴展,還有很多內容,這裏是總結不全面的,如果需要,請各位自行Google吧。

調試腳本程序

寫程序,肯定是離不開調試的,就是你再NB,也很少把複雜的東西一次搞定吧。所以,調試就是每個程序員必備的一項技能。

對於Shell的調試,內容比較多,這裏推薦一篇文章,好好閱讀這篇文章就足以了,搞定Shell的調試就不再是問題。看這裏

總結

這篇文章總結的比較零碎,也是花費業餘時間來總結的,很多地方可能總結的不全面,後期查閱的時候,再補吧。

果凍想-一個原創技術文章分享網站。

2014年12月21日 於深圳。

如果你覺的文章還不錯,可以關注果凍想微信公衆號,定期推送技術文章:
果凍想微信公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章