1. 程式人生 > >Linux Shell學習

Linux Shell學習

rgb 一個表 事先 nts 讀取 暫時 last copy 這一

1.Shell

shell本身是一個用C語言編寫的程序,它是用戶使用Unix/Linux的橋梁。用戶的大部分工作都是通過Shell完畢的。

Shell既是一種命令語言,又是一種程序設計語言。作為命令語言,它交互式地解釋和運行用戶輸入的命令。作為程序設計語言,它定義了各種變量和參數,並提供了很多在高級語言中才具有的控制結構,包含循環和分支。


2.Shell有兩種運行命令的方式:

  • 交互式(Interactive):解釋運行用戶的命令,用戶輸入一條命令,Shell就解釋運行一條。
  • 批處理(Batch):用戶事先寫一個Shell腳本(Script),當中有非常多條命令。讓Shell一次把這些命令運行完,而不必一條一條地敲命令。
Shell腳本和編程語言非常相似,也有變量和流程控制語句,但Shell腳本是解釋運行的,不須要編譯,Shell程序從腳本中一行一行讀取並運行這些命令。相當於一個用戶把腳本中的命令一行一行敲到Shell提示符下運行。


3.bash全然兼容sh。也就是說,用sh寫的腳本能夠不加改動的在bash中運行。

4.Shell支持自己定義變量。

定義變量時,變量名不加美元符號($),如:

  1. variableName="value"
註意,變量名和等號之間不能有空格(兩側都不能夠有空格)。這可能和你熟悉的全部編程語言都不一樣。同一時候,變量名的命名須遵循例如以下規則:
  • 間不能有空格,能夠使用下劃線(_)。

  • 不能使用標點符號。
  • 不能使用bash裏的keyword(可用help命令查看保留keyword)。

5.使用一個定義過的變量,僅僅要在變量名前面加美元符號($)就可以,如:





  1. your_name="mozhiyan"
  2. echo $your_name
  3. echo ${your_name}}
變量名外面的花括號是可選的,加不加都行,加花括號是為了幫助解釋器識別變量的邊界。比方以下這樣的情況:




  1. for skill in Ada Coffe Action Java
  2. do
  3. echo "I am good at ${skill}Script"
  4. done
假設不給skill變量加花括號,寫成echo "I am good at $skillScript",解釋器就會把$skillScript當成一個變量(其值為空)
,代碼運行結果就不是我們期望的樣子了。

推薦給全部變量加上花括號,這是個好的編程習慣。

6.僅僅讀變量

使用 readonly 命令能夠將變量定義為僅僅讀變量,僅僅讀變量的值不能被改變。

以下的樣例嘗試更改僅僅讀變量,結果報錯:
  1. #!/bin/bash
  2. myUrl="http://see.xidian.edu.cn/cpp/shell/"
  3. readonly myUrl
  4. myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
執行腳本,結果例如以下:
/bin/sh: NAME: This variable is read only.

7.刪除變量

使用 unset 命令能夠刪除變量。語法:
  1. unset variable_name
變量被刪除後不能再次使用;unset 命令不能刪除僅僅讀變量。

8.算術運算符

  1. if [ $a == $b ]
  2. then
  3. echo "a is equal to b"
  4. fi
註意:條件表達式要放在方括號之間,而且要有空格,比如 [$a==$b] 是錯誤的,必須寫成 [ $a == $b ]。

乘號(*)前邊必須加反斜杠(\)才幹實現乘法運算
算術運算符列表
運算符 說明 舉例
+ 加法 `expr $a + $b` 結果為 30。

- 減法 `expr $a - $b` 結果為 10。
* 乘法 `expr $a \* $b` 結果為 200

/ 除法 `expr $b / $a` 結果為 2。

% 取余 `expr $b % $a` 結果為 0。
= 賦值 a=$b 將把變量 b 的值賦給 a。
== 相等。用於比較兩個數字,同樣則返回 true。 [ $a == $b ] 返回 false。
!= 不相等。

用於比較兩個數字。不同樣則返回 true。

[ $a != $b ] 返回 true。



9.關系運算符

關系運算符僅僅支持數字,不支持字符串,除非字符串的值是數字。

關系運算符列表
運算符 說明 舉例
-eq 檢測兩個數是否相等。相等返回 true。 [ $a -eq $b ] 返回 true。
-ne 檢測兩個數是否相等。不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 檢測左邊的數是否大於右邊的,假設是,則返回 true。 [ $a -gt $b ] 返回 false。
-lt 檢測左邊的數是否小於右邊的,假設是,則返回 true。 [ $a -lt $b ] 返回 true。
-ge 檢測左邊的數是否大等於右邊的,假設是,則返回 true。 [ $a -ge $b ] 返回 false。
-le 檢測左邊的數是否小於等於右邊的,假設是,則返回 true。 [ $a -le $b ] 返回 true。



10.布爾運算符

布爾運算符列表
運算符 說明 舉例
! 非運算,表達式為 true 則返回 false,否則返回 true。 [ ! false ] 返回 true。

-o 或運算,有一個表達式為 true 則返回 true。

[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 與運算。兩個表達式都為 true 才返回 true。

[ $a -lt 20 -a $b -gt 100 ] 返回 false。


11.字符串運算符

字符串運算符列表
運算符 說明 舉例
= 檢測兩個字符串是否相等,相等返回 true。

[ $a = $b ] 返回 false。
!= 檢測兩個字符串是否相等,不相等返回 true。

[ $a != $b ] 返回 true。

-z 檢測字符串長度是否為0。為0返回 true。 [ -z $a ] 返回 false。
-n 檢測字符串長度是否為0,不為0返回 true。 [ -z $a ] 返回 true。

str 檢測字符串是否為空,不為空返回 true。 [ $a ] 返回 true。


12.文件測試運算符

文件測試運算符列表
操作符 說明 舉例
-b file 檢測文件是否是塊設備文件。假設是,則返回 true。 [ -b $file ] 返回 false。

-c file 檢測文件是否是字符設備文件。假設是,則返回 true。 [ -b $file ] 返回 false。
-d file 檢測文件是否是文件夾。假設是,則返回 true。 [ -d $file ] 返回 false。

-f file 檢測文件是否是普通文件(既不是文件夾,也不是設備文件),假設是,則返回 true。

[ -f $file ] 返回 true。

-g file 檢測文件是否設置了 SGID 位。假設是。則返回 true。 [ -g $file ] 返回 false。
-k file 檢測文件是否設置了粘著位(Sticky Bit),假設是。則返回 true。 [ -k $file ] 返回 false。
-p file 檢測文件是否是具名管道,假設是,則返回 true。 [ -p $file ] 返回 false。

-u file 檢測文件是否設置了 SUID 位,假設是,則返回 true。

[ -u $file ] 返回 false。
-r file 檢測文件是否可讀,假設是。則返回 true。 [ -r $file ] 返回 true。

-w file 檢測文件是否可寫,假設是,則返回 true。 [ -w $file ] 返回 true。
-x file 檢測文件是否可運行,假設是,則返回 true。

[ -x $file ] 返回 true。
-s file 檢測文件是否為空(文件大小是否大於0),不為空返回 true。

[ -s $file ] 返回 true。
-e file 檢測文件(包含文件夾)是否存在,假設是。則返回 true。 [ -e $file ] 返回 true。


13.凝視

以“#”開頭的行就是凝視,會被解釋器忽略。

sh裏沒有多行凝視。僅僅能每一行加一個#號

僅僅能像這樣:

  1. #--------------------------------------------
  2. # 這是一個自己主動打ipa的腳本,基於webfrogs的ipa-build書寫:
  3. # https://github.com/webfrogs/xcode_shell/blob/master/ipa-build
  4. # 功能:自己主動為etao ios app打包。產出物為14個渠道的ipa包
  5. # 特色:全自己主動打包,不須要輸入不論什麽參數
  6. #--------------------------------------------
假設在開發過程中,遇到大段的代碼須要暫時凝視起來。過一會兒又取消凝視,怎麽辦呢?每一行加個#符號太費力了,能夠把這一段要凝視的代碼用一對花括號括起來,定義成一個函數,沒有地方調用這個函數,這塊代碼就不會運行,達到了和凝視一樣的效果。

14.獲取字符串長度

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

提取字符串

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

查找字符串

  1. string="alibaba is a great company"
  2. echo `expr index "$string" is`#輸出3(i是第3個字符)

15.定義數組

在Shell中。用括號來表示數組,數組元素用“空格”符號切割開

定義數組的一般形式為:
array_name=(value1 ... valuen)
比如:

  1. array_name=(value0 value1 value2 value3)

還能夠單獨定義數組的各個分量:

  1. array_name[0]=value0
  2. array_name[1]=value1
  3. array_name[2]=value2
能夠不使用連續的下標。並且下標的範圍沒有限制。

讀取數組元素值的一般格式是:

${array_name[index]}
比如:

  1. valuen=${array_name[2]}
使用@ 或 * 能夠獲取數組中的全部元素,比如:

  1. ${array_name[*]}
  2. ${array_name[@]}
舉個樣例:
  1. #!/bin/sh
  2. NAME[0]="Zara"
  3. NAME[1]="Qadir"
  4. NAME[2]="Mahnaz"
  5. NAME[3]="Ayan"
  6. NAME[4]="Daisy"
  7. echo "First Method: ${NAME[*]}"
  8. echo "Second Method: ${NAME[@]}"
執行腳本。輸出:
$./test.sh
First Method: Zara Qadir Mahnaz Ayan Daisy
Second Method: Zara Qadir Mahnaz Ayan Daisy

獲取數組長度的方法與獲取字符串長度的方法同樣,比如: # 取得數組元素的個數 
  1. length=${#array_name[@]}
  2. # 或者
  3. length=${#array_name[*]}
  4. # 取得數組單個元素的長度
  5. lengthn=${#array_name[n]}

16.printf 命令用於格式化輸出

如同 echo 命令,printf 命令也能夠輸出簡單的字符串:
  1. $printf "Hello, Shell\n"
  2. Hello, Shell
  3. $
printf 不像 echo 那樣會自己主動換行,必須顯式加入換行符(\n)。



printf 命令的語法:

printf  format-string  [arguments...]
format-string 為格式控制字符串,arguments 為參數列表。
與C語言printf()函數的不同:
  • printf 命令不用加括號
  • format-string 能夠沒有引號,但最好加上,單引號雙引號均可。
  • 參數多於格式控制符(%)時,format-string 能夠重用。能夠將全部參數都轉換。
  • arguments 使用空格分隔,不用逗號。

請看以下的樣例:
  1. # format-string為雙引號
  2. $ printf "%d %s\n" 1 "abc"
  3. 1 abc
  4. # 單引號與雙引號效果一樣
  5. $ printf ‘%d %s\n 1 "abc"
  6. 1 abc
  7. # 沒有引號也能夠輸出
  8. $ printf %s abcdef
  9. abcdef
  10. # 格式僅僅指定了一個參數。但多出的參數仍然會依照該格式輸出,format-string 被重用
  11. $ printf %s abc def
  12. abcdef
  13. $ printf "%s\n" abc def
  14. abc
  15. def
  16. $ printf "%s %s %s\n" a b c d e f g h i j
  17. a b c
  18. d e f
  19. g h i
  20. j
  21. # 假設沒有 arguments,那麽 %s 用NULL取代。%d 用 0 取代
  22. $ printf "%s and %d \n"
  23. and 0
  24. # 假設以 %d 的格式來顯示字符串,那麽會有警告,提示無效的數字,此時默認置為 0
  25. $ printf "The first program always prints‘%s,%d\n‘" Hello Shell
  26. -bash: printf: Shell: invalid number
  27. The first program always prints ‘Hello,0‘
  28. $
註意。依據POSIX標準,浮點格式%e、%E、%f、%g與%G是“不須要被支持”。這是由於awk支持浮點預算,且有它自己的printf語句。

這樣Shell程序中須要將浮點數值進行格式化的打印時,可使用小型的awk程序實現。然而,內建於bash、ksh93和zsh中的printf命令都支持浮點格式。


17.for循環

for循環一般格式為:
for 變量 in 列表
do
    command1
    command2
    ...
    commandN
done
列表是一組值(數字、字符串等)組成的序列,每一個值通過空格分隔。每循環一次。就將列表中的下一個值賦給變量。



in 列表是可選的,假設不用它。for 循環使用命令行的位置參數。



比如,順序輸出當前列表中的數字:

  1. for loop in 1 2 3 4 5
  2. do
  3. echo "The value is: $loop"
  4. done
執行結果:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5

順序輸出字符串中的字符:
  1. for str in ‘This is a string‘
  2. do
  3. echo $str
  4. done
執行結果:
This is a string
假設不加引號則輸出:
This is a string
顯示主文件夾下以 .bash 開頭的文件:
  1. #!/bin/bash
  2. for FILE in $HOME/.bash*
  3. do
  4. echo $FILE
  5. done
執行結果:
/root/.bash_history
/root/.bash_logout
/root/.bashrc

18.函數

函數能夠讓我們將一個復雜功能劃分成若幹模塊。讓程序結構更加清晰,代碼反復利用率更高。

像其它編程語言一樣。Shell 也支持函數。

Shell 函數必須先定義後使用。

Shell 函數的定義格式例如以下:

function_name () {
    list of commands
    [ return value ]
}
假設你願意,也能夠在函數名前加上keyword function:
function function_name () {
    list of commands
    [ return value ]
}
函數返回值。能夠顯式添加return語句;假設不加。會將最後一條命令執行結果作為返回值。

Shell 函數返回值僅僅能是整數,一般用來表示函數運行成功與否。0表示成功,其它值表示失敗。

假設 return 其它數據,比方一個字符串。往往會得到錯誤提示:“numeric argument required”。



假設一定要讓函數返回字符串,那麽能夠先定義一個變量,用來接收函數的計算結果。腳本在須要的時候訪問這個變量來獲得函數返回值。
調用函數僅僅須要給出函數名。不須要加括號。


看一個帶有return語句的函數:
  1. #!/bin/bash
  2. funWithReturn(){
  3. echo "The function is to get the sum of two numbers..."
  4. echo -n "Input first number: "
  5. read aNum
  6. echo -n "Input another number: "
  7. read anotherNum
  8. echo "The two numbers are $aNum and $anotherNum !"
  9. return $(($aNum+$anotherNum))
  10. }
  11. funWithReturn
  12. # Capture value returnd by last command
  13. ret=$?
  14. echo "The sum of two numbers is $ret !"
執行結果:
The function is to get the sum of two numbers...
Input first number: 25
Input another number: 50
The two numbers are 25 and 50 !
The sum of two numbers is 75 !
函數返回值在調用該函數後通過 $? 來獲得
假設你希望直接從終端調用函數。能夠將函數定義在主文件夾下的 .profile 文件。這樣每次登錄後,在命令提示符後面輸入函數名字就能夠馬上調用

19.函數調用

在Shell中,調用函數時能夠向其傳遞參數。在函數體內部,通過 $n 的形式來獲取參數的值,比如。$1表示第一個參數,$2表示第二個參數...

帶參數的函數演示樣例:
復制純文本新窗體
  1. #!/bin/bash
  2. funWithParam(){
  3. echo "The value of the first parameter is $1 !"
  4. echo "The value of the second parameter is $2 !"
  5. echo "The value of the tenth parameter is $10 !" # $1的值 和 0
  6. echo "The value of the tenth parameter is ${10} !"
  7. echo "The value of the eleventh parameter is ${11} !"
  8. echo "The amount of the parameters is $# !" # 參數個數
  9. echo "The string of the parameters is $* !" # 傳遞給函數的全部參數
  10. }
  11. funWithParam 1 2 3 4 5 6 7 8 9 34 73
#!/bin/bash
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 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
執行腳本:
The value of the first parameter is 1 !
The value of the second parameter is 2 !
The value of the tenth parameter is 10 ! 
The value of the tenth parameter is 34 !
The value of the eleventh parameter is 73 !
The amount of the parameters is 11 !
The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"
註意,$10 不能獲取第十個參數,獲取第十個參數須要${10}。當n>=10時,須要使用${n}來獲取參數。


Linux Shell學習