linux下的shell腳本(基本)

Shell是一種腳本語言,那麼,就必須有解釋器來執行這些腳本,常見的腳本解釋器有:java

bash:是Linux標準默認的shell。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的縮寫,內部命令一共有40個。python

sh: 由Steve Bourne開發,是Bourne Shell的縮寫,sh 是Unix 標準默認的shell。linux

另外還有:ash、 csh、 ksh等。c++

 

常見的編程語言分爲兩類:一個是編譯型語言,如:c/c++/java等,它們遠行前所有一塊兒要通過編譯器的編譯。另外一個解釋型語言,執行時,須要使用解釋器一行一行地轉換爲代碼,如:awk, perl, python與shell等。shell

Shell 通過了POSIX的標準化,因此它是能夠在不一樣的linux系統上進行移植。編程

關於註釋的問題: 在shell中使用#進行註釋,注意,sh裏面沒有多行註釋,只能每一行加一個#號;數組

第一個shell腳本程序:

#!/bin/bash
# 上面中的 #! 是一種約定標記, 它能夠告訴系統這個腳本須要什麼樣的解釋器來執行;

echo "Hello, world!"

 

變量:

定義變量:bash

country="China"
Number=100

注意: 1,變量名和等號之間不能有空格;編程語言

2,首個字符必須爲字母(a-z,A-Z)。函數

3, 中間不能有空格,可使用下劃線(_)。

4, 不能使用標點符號。

5, 不能使用bash裏的關鍵字(可用help命令查看保留關鍵字)。

使用變量:

只須要在一個定義過的變量前面加上美圓符號 $ 就能夠了, 另外,對於變量的{} 是能夠選擇的, 它的目的爲幫助解釋器識別變量的邊界.

country="China"

echo $country
echo ${country}
echo "I love my ${country}abcd!"
#這個須要有{}的;

重定義變量: 直接把變量從新像開始定義的那樣子賦值就能夠了:

country="China"
country="ribenguizi"

只讀變量: 用 readonly 命令 能夠把變量字義爲只讀變量。

readonly country="China"
#或
country="China"
readonly country

刪除變量: 使用unset命令能夠刪除變量,可是不能刪除只讀的變量。用法:

unset variable_name

變量類型

運行shell時,會同時存在三種變量:

1) 局部變量

局部變量在腳本或命令中定義,僅在當前shell實例中有效,其餘shell啓動的程序不能訪問局部變量。

2) 環境變量

全部的程序,包括shell啓動的程序,都能訪問環境變量,有些程序須要環境變量來保證其正常運行。必要的時候shell腳本也能夠定義環境變量。

3) shell變量

shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行

 

特殊變量:

image

$* 和 $@ 的區別爲: $* 和 $@ 都表示傳遞給函數或腳本的全部參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出全部參數。可是當它們被雙引號(" ")包含時,"$*" 會將全部的參數做爲一個總體,以"$1 $2 … $n"的形式輸出全部參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出全部參數。

$? 能夠獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行後的返回結果。退出狀態是一個數字,通常狀況下,大部分命令執行成功會返回 0,失敗返回 1。

 

Shell中的替換

轉義符:

在echo中能夠用於的轉義符有:

image

使用 echo 命令的 –E 選項禁止轉義,默認也是不轉義的; 使用 –n 選項能夠禁止插入換行符;

使用 echo 命令的 –e 選項能夠對轉義字符進行替換。

另外,注意,通過個人實驗,獲得:

echo "\\"        #獲得 \
echo -e "\\"   #獲得  \

echo "\\\\"        #獲得 \\
echo -e "\\"       #獲得  \

命令替換:

它的意思就是說咱們把一個命令的輸出賦值給一個變量,方法爲把命令用反引號(在Esc下方)引發來.  好比:

directory=`pwd`
echo $directory

變量替換:

能夠根據變量的狀態(是否爲空、是否認義等)來改變它的值.

image

 

Shell運算符

算數運算符:

原生bash不支持簡單的數學運算,可是能夠經過其餘命令來實現,例如 awk 和 expr. 下面使用expr進行;  expr是一款表達式計算工具,使用它能夠完成表達式的求值操做;

image

好比:

複製代碼

a=10
b=20
expr $a + $b
expr $a - $b
expr $a \* $b
expr $a / $b
expr $a % $b
a=$b

複製代碼

注意: 1. 在expr中的乖號爲:\*

2. 在 expr中的 表達式與運算符之間要有空格,不然錯誤;

3. 在[ $a == $b ]與[ $a != $b ]中,要須要在方括號與變量以及變量與運算符之間也須要有括號, 不然爲錯誤的。(親測過)

關係運算符:

只支持數字,不支持字符串,除非字符串的值是數字。常見的有:

image

注意:也別忘記了空格;

布爾運算符:

image

字符串運算符:

image

文件測試運算符:

檢測 Unix 文件的各類屬性。

image

 

Shell中的字符串

單引號的限制:

  1. 單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
  2. 單引號字串中不能出現單引號(對單引號使用轉義符後也不行)。

雙引號的優勢:

  1. 雙引號裏能夠有變量
  2. 雙引號裏能夠出現轉義字符

拼接字符串:

country="China"
echo "hello, $country"
#也能夠
echo "hello, "$country" "

獲取字符串長度:

string="abcd"
echo ${#string} #輸出 4

提取子字符串:

string="alibaba is a great company"
echo ${string:1:4} #輸出liba

查找子字符串:

string="alibaba is a great company"
echo `expr index "$string" is`

 

處理路經的字符串:

例如:當一個路徑爲 /home/xiaoming/1.txt時,如何怎麼它的路徑(不帶文件) 和如何獲得它的文件名??

獲得文件名使用 bashname命令:  

複製代碼

#  參數:
#  -a,表示處理多個路徑;
# -s, 用於去掉指定的文件的後綴名;

 basename /home/yin/1.txt          -> 1.txt

 basename -a /home/yin/1.txt /home/zhai/2.sh     -> 
1.txt
2.sh basename -s .txt /home/yin/1.txt    -> 1
 basename /home/yin/1.txt .txt       -> 1

複製代碼

獲得路徑名(不帶文件名)使用 dirname命令:

複製代碼

參數:沒有啥參數;

//例子:
 dirname /usr/bin/          -> /usr
 dirname dir1/str dir2/str  ->
dir1
dir2
dirname stdio.h            -> .

複製代碼

 

Shell的數組:

bash支持一維數組, 不支持多維數組, 它的下標從0開始編號. 用下標[n] 獲取數組元素;

定義數組:

在shell中用括號表示數組,元素用空格分開。 如:

array_name=(value0 value1 value2 value3)

也能夠單獨定義數組的各個份量,能夠不使用連續的下標,並且下標的範圍沒有限制。如:

array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

讀取數組:

讀取某個下標的元素通常格式爲:

${array_name[index]}

讀取數組的所有元素,用@或*

${array_name[*]}
${array_name[@]}

獲取數組的信息:

取得數組元素的個數:

length=${#array_name[@]}
#或
length=${#array_name[*]}

獲取數組的下標:

length=${!array_name[@]}
#或
length=${!array_name[*]}

取得數組單個元素的長度:

lengthn=${#array_name[n]}

 

printf函數:

它與c語言中的printf類似,不過也有不一樣,下面列出它的不一樣的地方:

  1. printf 命令不用加括號
  2. format-string 能夠沒有引號,但最好加上,單引號雙引號都可。
  3. 參數多於格式控制符(%)時,format-string 能夠重用,能夠將全部參數都轉換。
  4. arguments 使用空格分隔,不用逗號。

下面爲例子:

複製代碼

# format-string爲雙引號
$ printf "%d %s\n" 1 "abc"
1 abc
# 單引號與雙引號效果同樣 
$ printf '%d %s\n' 1 "abc" 
1 abc
# 沒有引號也能夠輸出
$ printf %s abcdef
abcdef
# 格式只指定了一個參數,但多出的參數仍然會按照該格式輸出,format-string 被重用
$ printf %s abc def
abcdef
$ printf "%s\n" abc def
abc
def
$ printf "%s %s %s\n" a b c d e f g h i j
a b c
d e f
g h i
j
# 若是沒有 arguments,那麼 %s 用NULL代替,%d 用 0 代替
$ printf "%s and %d \n" 
and 0
# 若是以 %d 的格式來顯示字符串,那麼會有警告,提示無效的數字,此時默認置爲 0
$ printf "The first program always prints'%s,%d\n'" Hello Shell
-bash: printf: Shell: invalid number
The first program always prints 'Hello,0'
$

複製代碼

 

Shell中條件語句

if 語句

包括:1, if [ 表達式 ] then  語句  fi

2. if [ 表達式 ] then 語句 else 語句 fi

3.  if [ 表達式] then 語句  elif[ 表達式 ] then 語句 elif[ 表達式 ] then 語句   …… fi

例子:

複製代碼

a=10
b=20
if [ $a == $b ]
then
   echo "a is equal to b"
else
   echo "a is not equal to b"
fi

複製代碼

另外:if ... else 語句也能夠寫成一行,以命令的方式來運行,像這樣:

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;

其中,test 命令用於檢查某個條件是否成立,與方括號([ ])相似。

case …… esac語句

case ... esac 與其餘語言中的 switch ... case 語句相似,是一種多分枝選擇結構。case語句格式以下:

複製代碼

case 值 in
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

複製代碼

其中, 1. 取值後面必須爲關鍵字 in,每一模式必須以右括號結束。取值能夠爲變量或常數。匹配發現取值符合某一模式後,其間全部命令開始執行直至 ;;。;; 與其餘語言中的 break 相似,意思是跳到整個 case 語句的最後。2. 若是無一匹配模式,使用星號 * 捕獲該值,再執行後面的命令。

 

Shell 的循環語句

for 循環 

  通常格式爲:

複製代碼

for 變量 in 列表
do
    command1
    command2
    ...
    commandN
done

複製代碼

注意:列表是一組值(數字、字符串等)組成的序列,每一個值經過空格分隔。每循環一次,就將列表中的下一個值賦給變量。       例如:

順序輸出當前列表的數字:

for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

顯示主目錄下以 .bash 開頭的文件:

#!/bin/bash
for FILE in $HOME/.bash*
do
   echo $FILE
done

while循環

通常格式爲:

while command
do
   Statement(s) to be executed if command is true
done

例如:

COUNTER=0
while [ $COUNTER -lt 5 ]
do
    COUNTER='expr $COUNTER+1'
    echo $COUNTER
done

until 循環

until 循環執行一系列命令直至條件爲 true 時中止。until 循環與 while 循環在處理方式上恰好相反。    經常使用格式爲:

until command
do
   Statement(s) to be executed until command is true
done

command 通常爲條件表達式,若是返回值爲 false,則繼續執行循環體內的語句,不然跳出循環。

 

相似地, 在循環中使用 break 與continue 跳出循環。    另外,break 命令後面還能夠跟一個整數,表示跳出第幾層循環。

 

Shell函數

Shell函數必須先定義後使用,定義以下,

function_name () {
    list of commands
    [ return value ]
}

也能夠加上function關鍵字:

function function_name () {
    list of commands
    [ return value ]
}

注意:1. 調用函數只須要給出函數名,不須要加括號。

2. 函數返回值,能夠顯式增長return語句;若是不加,會將最後一條命令運行結果做爲返回值。

3. Shell 函數返回值只能是整數,通常用來表示函數執行成功與否,0表示成功,其餘值表示失敗。

4. 函數的參數能夠經過 $n  獲得.如:

複製代碼

funWithParam(){
    echo "The value of the first parameter is $1 !"
    echo "The value of the second parameter is $2 !"
    echo "The value of the tenth parameter is ${10} !"
    echo "The value of the eleventh parameter is ${11} !"
    echo "The amount of the parameters is $# !"  # 參數個數
    echo "The string of the parameters is $* !"  # 傳遞給函數的全部參數
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

複製代碼

5. 像刪除變量同樣,刪除函數也可使用 unset 命令,不過要加上 .f 選項,以下所示:
unset .f function_name

 

shell的文件包含:

Shell 也能夠包含外部腳本,將外部腳本的內容合併到當前腳本。使用:

. filename
#或
source filename

1. 兩種方式的效果相同,簡單起見,通常使用點號(.),可是注意點號(.)和文件名中間有一空格。

2. 被包含腳本不須要有執行權限。

相關文章
相關標籤/搜索