########認識shell
1.Unix/Linux上常見的Shell腳本解釋器有bash、sh、csh、ksh等,習慣上把它們稱作一種Shell。我們常說有多少種Shell,其實說的是Shell腳本解釋器。
注意:bash是 Bourne Again Shell 的縮寫,是linux標準的默認shell ,它基於Bourne shell,吸收了C shell和Korn shell的一些特性。bash完全兼容sh,也就是說,用sh寫的腳本可以不加修改的在bash中執行。
2.#!/bin/bash
“#!” 是一個約定的標記,它告訴系統這個腳本需要什麼解釋器來執行,即使用哪一種Shell。echo命令用於向窗口輸出文本。
3.chmod +x ./test.sh腳本添加執行權限
注意,一定要寫成./test.sh,而不是test.sh。運行其它二進制的程序也一樣,直接寫test.sh,linux系統會去PATH裏尋找有沒有叫test.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH裏,你的當前目錄通常不在PATH裏,所以寫成test.sh是會找不到命令的,要用./test.sh告訴系統說,就在當前目錄找。
4.read 命令從stdin獲取輸入並賦值給Person變量,最後在stdout上輸出:
#!/bin/bash
#Author:HJY
#Script follows here:[email protected]:/root
echo "What's your name?"
read Person
echo "Hello,$Person"
########shell變量
1.myNum=8
注意,變量名和等號之間不能有空格
2.使用一個定義過的變量,只要在變量名前面加美元符號($)即可
my_name="hjy"
echo $my_name
echo ${my_name}
變量名外面的花括號是可選的,加不加都行,加花括號是爲了幫助解釋器識別變量的邊界
3.已定義的變量,可以被重新定義
myUrl="http://see.xidian.edu.cn/cpp/linux/"
echo ${myUrl}
myUrl="http://see.xidian.edu.cn/cpp/shell/"
echo ${myUrl}
4.使用 readonly 命令可以將變量定義爲只讀變量,只讀變量的值不能被改變。
5.使用 unset 命令可以刪除變量。語法:
unset variable_name
變量被刪除後不能再次使用;unset 命令不能刪除只讀變量
########shell特殊變量
1.包含其他字符的變量有特殊含義,稱爲特殊變量。
$0:當前腳本的文件名
$n:傳遞給腳本或函數的參數。n是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2。
$#:傳遞給腳本或函數的參數個數。
$*:傳遞給腳本或函數的所有參數。
$@:傳遞給腳本或函數的所有參數。被雙引號(" ")包含時,與 $* 稍有不同,區別如下2:
$?:上個命令的退出狀態,或函數的返回值。
$$:當前Shell進程ID。對於Shell腳本,就是這些腳本所在的進程ID。
示例腳本:
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "Second Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
執行腳本$./test.sh Tom Bob
File Name : ./test.sh
First Parameter : Tom
Second Parameter : Bob
Quoted Values: Tom Bob
Quoted Values: Tom Bob
Total Number of Parameters : 2
2.$*和$@的區別:
$*和$@都表示傳遞給函數或腳本的所有參數,不被雙引號(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數。
但當它們被雙引號(" ")包含時,"$*" 會將所有的參數作爲一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@" 會將各個參數分開,以"$1" "$2" … "$n" 的形式輸出所有參數。
eg:for var in "$*"【去掉雙引號,執行後輸出的是整體】
do
echo "$var"
done
執行:sh test.sh a b c
3.$? 也可以表示函數的返回值
4.echo -e 其中-e表示對轉義字符替換,如果不使用 -e 選項,將會原樣輸出
echo -E 其中-E禁止轉義,默認也是不轉義的;使用 -n 選項可以禁止插入換行符
轉義字符:含義
\\:反斜槓
\a:警報,響鈴
\b:退格(刪除鍵)
\f:換頁(FF),將當前位置移到下頁開頭
\n:換行
\r:回車
\t:水平製表符(tab鍵)
\v:垂直製表符
5.命令替換的語法:
`command`
注意是反引號,不是單引號,此鍵位於Esc鍵下方。
6.可以使用的變量替換形式
形式:說明
${var}:變量本來的值
${var:-word}:如果變量 var 爲空或已被刪除(unset),那麼返回 word,但不改變 var 的值。
${var:=word}:如果變量 var 爲空或已被刪除(unset),那麼返回 word,並將 var 的值設置爲 word。
${var:?message}:如果變量 var 爲空或已被刪除(unset),那麼將消息 message 送到標準錯誤輸出,可以用來檢測變量 var 是否可以被正常賦值。若此替換出現在Shell腳本中,那麼腳本將停止運行。
${var:+word}:如果變量 var 被定義,那麼返回 word,但不改變 var 的值。
########shell運算符
1.算術運算符
運算符 說明 舉例
+ 加法 `expr $a + $b` 結果爲30。(a=10 b=20)
- 減法 `expr $a - $b` 結果爲 10。
* 乘法 `expr $a \* $b` 結果爲 200。
/ 除法 `expr $b / $a` 結果爲 2。
% 取餘 `expr $b % $a` 結果爲 0。
= 賦值 a=$b 將把變量 b 的值賦給 a。
== 相等。 用於比較兩個數字,相同則返回 true。 [ $a == $b ]
!= 不相等。 比較兩個數字,不相同則返回 true。 [ $a != $b ]
原生bash不支持簡單的數學運算,但是可以通過其他命令來實現,如awk和expr,expr最常用。
expr 是一款表達式計算工具,使用它能完成表達式的求值操作。
腳本示例:
val=`expr 2 + 2`
echo "Total value : $val"
執行結果:Total value : 4
注意:
等號與val無空格
表達式和運算符之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與我們熟悉的大多數編程語言不一樣。
完整的表達式要被 ` `包含,注意這個字符不是常用的單引號,此鍵位於Esc鍵下方。
2.關係運算符列表
運算符 說明 舉例
-eq 檢測兩個數是否相等,相等返回 true。 [ $a -eq $b ]
-ne 檢測兩個數是否相等,不相等返回 true。 [ $a -ne $b ]
-gt 檢測左邊的數是否大於右邊的,如果是,則返回 true。 [ $a -gt $b ]
-lt 檢測左邊的數是否小於右邊的,如果是,則返回 true。 [ $a -lt $b ]
-ge 檢測左邊的數是否大等於右邊的,如果是,則返回 true。 [ $a -ge $b ]
-le 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。[ $a -le $b ]
注意:關係運算符只支持數字,不支持字符串,除非字符串的值是數字。
3.布爾運算符列表
運算符 說明 舉例
! 非運算,表達式爲 true 則返回 false,否則返回 true。 [ ! false ]
-o 或運算,有一個表達式爲 true 則返回 true。 [ $a -lt 20 -o $b -gt 100 ]
-a 與運算,兩個表達式都爲 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ]
4.字符穿運算列表
運算符 說明 舉例
= 檢測兩個字符串是否相等,相等返回 true。 [ $a = $b ]
!= 檢測兩個字符串是否相等,不相等返回 true。 [ $a != $b ]
-z 檢測字符串長度是否爲0,爲0返回 true。 [ -z $a ]
-n 檢測字符串長度是否爲0,不爲0返回 true。 [ -n $a ]
str 檢測字符串是否爲空,不爲空返回 true。 [ $a ]
5.文件測試運算符列表
操作符 說明 舉例
-b file 檢測文件是否是塊設備文件,如果是,則返回 true。 [ -b $file ]
-c file 檢測文件是否是字符設備文件,如果是,則返回 true。 [ -b $file ]
-d file 檢測文件是否是目錄,如果是,則返回 true。 [ -d $file ]
-f file 檢測文件是否是普通文件,如果是,則返回 true。 [ -f $file ]
-g file 檢測文件是否設置了 SGID 位,如果是,則返回 true。 [ -g $file ]
-k file 檢測文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。 [ -k $file ]
-p file 檢測文件是否是具名管道,如果是,則返回 true。 [ -p $file ]
-u file 檢測文件是否設置了 SUID 位,如果是,則返回 true。 [ -u $file ]
-r file 檢測文件是否可讀,如果是,則返回 true。 [ -r $file ]
-w file 檢測文件是否可寫,如果是,則返回 true。 [ -w $file ]
-x file 檢測文件是否可執行,如果是,則返回 true。 [ -x $file ]
-s file 檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。 [ -s $file ]
-e file 檢測文件(包括目錄)是否存在,如果是,則返回 true。 [ -e $file ]
########shell註釋
如果在開發過程中,遇到大段的代碼需要臨時註釋起來,過一會兒又取消註釋,怎麼辦呢?每一行加個#符號太費力了,可以把這一段要註釋的代碼用一對花括號括起來,定義成一個函數,沒有地方調用這個函數,這塊代碼就不會執行,達到了和註釋一樣的效果。
########Shell字符串
1.單引號字符串的限制:
單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
單引號字串中不能出現單引號(對單引號使用轉義符後也不行)。
2.雙引號的優點:
雙引號裏可以有變量
雙引號裏可以出現轉義字符
#######Shell數組
1.在Shell中,用括號來表示數組,數組元素用“空格”符號分割開。定義數組的一般形式爲:
array_name=(value1 ... valuen)
2.讀取數組
1)讀取數組元素值的一般格式是:
${array_name[index]}
使用@ 或 * 可以獲取數組中的所有元素,例如:
${array_name[*]}
${array_name[@]}
2)獲取數組的長度
獲取數組長度的方法與獲取字符串長度的方法相同,例如:
# 取得數組元素的個數
length=${#array_name[@]}
length=${#array_name[*]}
# 取得數組單個元素的長度
length=${#array_name[n]}
########Shell echo命令
1.echo命令,用於在屏幕上打印出指定的字符串
如果變量與其它字符相連的話,需要使用大括號({ }):
mouth=8
echo "${mouth}-1-2009"
2. 顯示結果重定向至文件
echo "It is a test" > myfile
########Shell printf命令
1.printf 命令用於格式化輸出, 是echo命令的增強版,printf 不像 echo 那樣會自動換行,必須顯式添加換行符(\n)。
2.printf 命令的語法:
printf format-string [arguments...]
format-string爲格式控制字符串,arguments爲參數列表。如果沒有 arguments,那麼%s用NULL代替,%d用0代替
這裏僅說明與C語言printf()函數的不同:
printf 命令不用加括號
format-string 可以沒有引號,但最好加上,單引號雙引號均可。
參數多於格式控制符(%)時,format-string 可以重用,可以將所有參數都轉換。
arguments 使用空格分隔,不用逗號。
######Shell if語句
1.Shell 有三種 if ... else 語句:
if ... fi 語句;
if ... else ... fi 語句;
if ... elif ... else ... fi 語句。
2.if ... else 語句也經常與 test 命令結合使用,如下:
if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
########Shell case esac語句
1.case ... esac 與其他語言中的 switch...case 語句類似,是一種多分枝選擇結構。
case 語句匹配一個值或一個模式,如果匹配成功,執行相匹配的命令。case語句格式如下:
case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac
注意:
取值後面必須爲 in ,每一模式必須以右括號結束
;;符號與其他語言中的break類似,意思是跳到整個case語句的最後。
########Shell for循環
1.for循環一般格式爲:
for 變量 in 列表
do
command1
command2
...
commandN
done
示例腳本:顯示主目錄下以 .bash 開頭的文件
#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
執行結果:
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc
########Shell while循環
1.while循環用於不斷執行一系列命令,也用於從輸入文件中讀取數據;命令通常爲測試條件。其格式爲:
while command
do
Statement(s) to be executed if command is true
done
示例腳本:while循環可用於讀取鍵盤信息。輸入信息被設置爲變量FILM,按<Ctrl-D>結束循環。
echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
echo " Great film is the $FILM"
done
命令執行完畢,控制返回循環頂部,從頭開始直至測試條件爲假。
########Shell break和continue命令跳出循環
1.break命令允許跳出所有循環(終止執行後面的所有循環)。
break n 表示跳出第n層循環
示例腳本:
while :
do
echo -n "The number is (1-3):"
read num
case $num in
1|2|3)echo "Your number is $num"
;;
*)echo "The number is not between 1 to 3,game over!"
break
;;
esac
done
2.continue命令與break命令類似,只有一點差別,它不會跳出所有循環,僅僅跳出當前循環。
continue 後面也可以跟一個數字,表示跳出第幾層循環。
示例腳本:echo "Game over!"永遠不會被執行
while :
do
echo -n "The number is (1-3):"
read num
case $num in
1|2|3)echo "Your number is $num"
;;
*)echo "The number is not between 1 to 3!"
continue
echo "Game over!"
;;
esac
done
########Shell 函數
1.Shell 函數的定義格式如下:
function_name () {
list of commands
[ return value ]
}
函數返回值,可以顯式增加return語句;如果不加,會將最後一條命令運行結果作爲返回值。
2.刪除函數也可以使用 unset 命令,不過要加上 .f 選項,如下所示:
$unset .f function_name
########Shell 函數參數
1.調用函數時可以向其傳遞參數。在函數體內部,通過 $n 的形式來獲取參數的值,例如,$1表示第一個參數,$2表示第二個參數...
注意,$10 不能獲取第十個參數,獲取第十個參數需要${10}。當n>=10時,需要使用${n}來獲取參數。
########Shell 輸入輸出重定向
1.linux命令默認從標準輸入設備(stdin)獲取輸入,將結果輸出到標準輸出設備(stdout)顯示。
一般情況下,標準輸入設備就是鍵盤,標準輸出設備就是終端,即顯示器。
2.輸出重定向的語法爲:
$ command > file
使用 >> 追加到文件末尾
echo test >> file
3.輸入重定向的語法爲:
command < file
4.重定向命令列表
命令 說明
command > file 將輸出重定向到 file。
command < file 將輸入重定向到 file。
command >> file 將輸出以追加的方式重定向到 file。
n > file 將文件描述符爲 n 的文件重定向到 file。
n >> file 將文件描述符爲 n 的文件以追加的方式重定向到 file。
n >& m 將輸出文件 m 和 n 合併。
n <& m 將輸入文件 m 和 n 合併。
<< tag 將開始標記 tag 和結束標記 tag 之間的內容作爲輸入。
5.重定向深入講解
一般情況下,每個 Linux 命令運行時都會打開三個文件:
標準輸入文件(stdin):stdin的文件描述符爲0,Linux程序默認從stdin讀取數據。
標準輸出文件(stdout):stdout的文件描述符爲1,Linux程序默認向stdout輸出數據。
標準錯誤文件(stderr):stderr的文件描述符爲2,Linux程序會向stderr流中寫入錯誤信息
1)如果希望stderr重定向到 file,可以這樣寫:
$command 2 > file
2)如果希望 stderr 追加到 file 文件末尾,可以這樣寫:
$command 2 >> file
3)如果希望將 stdout 和 stderr 合併後重定向到 file,可以這樣寫:
$command > file 2>&1 或 $command >> file 2>&1
4)如果希望對 stdin 和 stdout 都重定向,可以這樣寫:
$command < file1 >file2
command 命令將 stdin 重定向到 file1,將 stdout 重定向到 file2。
6. /dev/null 文件
如果希望執行某個命令,但又不希望在屏幕上顯示輸出結果,那麼可以將輸出重定向到/dev/null
注意:/dev/null 是一個特殊的文件,寫入到它的內容都會被丟棄;如果嘗試從該文件讀取內容,那麼什麼也讀不到。但是 /dev/null 文件非常有用,將命令的輸出重定向到它,會起到”禁止輸出“的效果。
########Shell 文件包含
1.Shell 也可以包含外部腳本,將外部腳本的內容合併到當前腳本
. filename 或 source filename
兩種方式的效果相同,一般使用點號(.),但是注意點號(.)和文件名中間有一空格。