Shell 教程php
Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 的橋樑。Shell 既是一種命令語言,又是一種程序設計語言。html
Shell 腳本linux
Shell 腳本(shell script),是一種爲 shell 編寫的腳本程序。shell
本教程關注的是 Bash,也就是 Bourne Again Shell編程
實例新建一個文件 test.sh數組
#!/bin/bash
echo "Hello World !"運行實例 »bash
#! 是一個約定的標記,它告訴系統這個腳本須要什麼解釋器來執行,即便用哪種 Shell。編程語言
echo 命令用於向窗口輸出文本。學習
運行 Shell 腳本有兩種方法:測試
一、做爲可執行程序
將上面的代碼保存爲 test.sh,並 cd 到相應目錄:
chmod +x ./test.sh #使腳本具備執行權限
./test.sh #執行腳本
注意,必定要寫成 ./test.sh,而不是 test.sh,運行其它二進制的程序也同樣,直接寫 test.sh,linux 系統會去 PATH 裏尋找有沒有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 裏,你的當前目錄一般不在 PATH 裏,因此寫成 test.sh 是會找不到命令的,要用 ./test.sh 告訴系統說,就在當前目錄找。
二、做爲解釋器參數
這種運行方式是,直接運行解釋器,其參數就是 shell 腳本的文件名,如:
/bin/sh test.sh
/bin/php test.php
Shell 變量
定義變量時,如:
your_name="runoob.com"
注意,變量名和等號之間不能有空格,這可能和你熟悉的全部編程語言都不同。同時,變量名的命名須遵循以下規則:
命名只能使用英文字母,數字和下劃線,首個字符不能以數字開頭。
中間不能有空格,可使用下劃線(_)。
不能使用標點符號。
不能使用bash裏的關鍵字(可用help命令查看保留關鍵字)。
使用變量
使用一個定義過的變量,只要在變量名前面加美圓符號便可,如:
your_name="qinjx"
echo $your_name
echo ${your_name}
最好加{}
已定義的變量,能夠被從新定義,如:
your_name="tom"
echo $your_name
your_name="alibaba"
echo $your_name
只讀變量
使用 readonly 命令能夠將變量定義爲只讀變量,只讀變量的值不能被改變。
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
刪除變量
使用 unset 命令能夠刪除變量。語法:
unset variable_name
變量被刪除後不能再次使用。unset 命令不能刪除只讀變量。
變量類型
運行shell時,會同時存在三種變量:
1) 局部變量 局部變量在腳本或命令中定義,僅在當前shell實例中有效,其餘shell啓動的程序不能訪問局部變量。
2) 環境變量 全部的程序,包括shell啓動的程序,都能訪問環境變量,有些程序須要環境變量來保證其正常運行。必要的時候shell腳本也能夠定義環境變量。
3) shell變量 shell變量是由shell程序設置的特殊變量。shell變量中有一部分是環境變量,有一部分是局部變量,這些變量保證了shell的正常運行
Shell 字符串
字符串能夠用單引號,也能夠用雙引號,也能夠不用引號。單雙引號的區別跟PHP相似。
單引號
str='this is a string'
單引號字符串的限制:
單引號裏的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
單引號字串中不能出現單獨一個的單引號(對單引號使用轉義符後也不行),但可成對出現,做爲字符串拼接使用。
雙引號
your_name='runoob'
str="Hello, I know you are \"$your_name\"! \n"
echo $str
輸出結果爲:
Hello, I know you are "runoob"!
雙引號的優勢:
雙引號裏能夠有變量
雙引號裏能夠出現轉義字符
例
拼接字符串
your_name="runoob"
# 使用雙引號拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
# 使用單引號拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
輸出結果爲:
hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !
獲取字符串長度
string="abcd"
echo ${#string} #輸出 4
提取子字符串
如下實例從字符串第 2 個字符開始截取 4 個字符:
string="runoob is a great site"
echo ${string:1:4} # 輸出 unoo
查找子字符串
查找字符 i 或 o 的位置(哪一個字母先出現就計算哪一個):
string="runoob is a great site"
echo `expr index "$string" io` # 輸出 4
注意: 以上腳本中 ` 是反引號,而不是單引號 ',不要看錯了哦。
Shell 數組
bash支持一維數組(不支持多維數組),而且沒有限定數組的大小。
相似於 C 語言,數組元素的下標由 0 開始編號。獲取數組中的元素要利用下標,下標能夠是整數或算術表達式,其值應大於或等於 0。
定義數組
在 Shell 中,用括號來表示數組,數組元素用"空格"符號分割開。定義數組的通常形式爲:
數組名=(值1 值2 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
還能夠單獨定義數組的各個份量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
能夠不使用連續的下標,並且下標的範圍沒有限制。
讀取數組
讀取數組元素值的通常格式是:
${數組名[下標]}
例如:
valuen=${array_name[n]}
使用 @ 符號能夠獲取數組中的全部元素,例如:
echo ${array_name[@]}
獲取數組的長度
獲取數組長度的方法與獲取字符串長度的方法相同,例如:
# 取得數組元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得數組單個元素的長度
lengthn=${#array_name[n]}
Shell 註釋
以 # 開頭的行就是註釋,會被解釋器忽略。
多行註釋
多行註釋還可使用如下格式:
:<<EOF
註釋內容...
註釋內容...
註釋內容...
EOF
Shell 傳遞參數
腳本內獲取參數的格式爲:$n
echo "Shell 傳遞參數實例!";
echo "執行的文件名:$0";
echo "第一個參數爲:$1";
echo "第二個參數爲:$2";
參數處理 |
說明 |
$# |
傳遞到腳本的參數個數 |
$* |
以一個單字符串顯示全部向腳本傳遞的參數。 |
$$ |
腳本運行的當前進程ID號 |
$! |
後臺運行的最後一個進程的ID號 |
$@ |
與$*相同,可是使用時加引號,並在引號中返回每一個參數。 |
$- |
顯示Shell使用的當前選項,與set命令功能相同。 |
$? |
顯示最後命令的退出狀態。0表示沒有錯誤,其餘任何值代表有錯誤。 |
$* 與 $@ 區別:
相同點:都是引用全部參數。
不一樣點:只有在雙引號中體現出來。假設在腳本運行時寫了三個參數 一、二、3,,則 " * " 等價於 "1 2 3"(傳遞了一個參數),而 "@" 等價於 "1" "2" "3"(傳遞了三個參數)。
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
執行腳本,輸出結果以下所示:
$ chmod +x test.sh
$ ./test.sh 1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3
Shell 數組
array_name=(value1 ... valuen)
例:my_array=(A B "C" D)
咱們也可使用下標來定義數組:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
讀取數組
${array_name[index]}
獲取數組中的全部元素
使用@ 或 * 能夠獲取數組中的全部元素,
echo "數組的元素爲: ${my_array[*]}"
echo "數組的元素爲: ${my_array[@]}"
獲取數組的長度
echo "數組元素個數爲: ${#my_array[*]}"
echo "數組元素個數爲: ${#my_array[@]}"
Shell 基本運算符
Shell 和其餘編程語言同樣,支持多種運算符,包括:
算數運算符
關係運算符
布爾運算符
字符串運算符
文件測試運算符
原生bash不支持簡單的數學運算,可是能夠經過其餘命令來實現,例如 awk 和 expr,expr 最經常使用。
例如,兩個數相加(注意使用的是反引號 ` 而不是單引號 '):
#!/bin/bash
val=`expr 2 + 2`
echo "兩數之和爲 : $val"
注意:
表達式和運算符之間要有空格,例如 2+2 是不對的,必須寫成 2 + 2,這與咱們熟悉的大多數編程語言不同。
完整的表達式要被 ` ` 包含,注意這個字符不是經常使用的單引號,在 Esc 鍵下邊。
算術運算符
下表列出了經常使用的算術運算符,假定變量 a 爲 10,變量 b 爲 20:
運算符 |
說明 |
舉例 |
+ |
加法 |
`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。 |
注意:條件表達式要放在方括號之間,而且要有空格,例如: [$a==$b] 是錯誤的,必須寫成 [ $a == $b ]。
例:
val=`expr $a + $b`
echo "a + b : $val"
關係運算符
關係運算符只支持數字,不支持字符串,除非字符串的值是數字。
下表列出了經常使用的關係運算符,假定變量 a 爲 10,變量 b 爲 20:
運算符 |
說明 |
舉例 |
-eq |
檢測兩個數是否相等,相等返回 true。 |
[ $a -eq $b ] 返回 false。 |
-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。 |
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等於 b"
else
echo "$a -eq $b: a 不等於 b"
布爾運算符
下表列出了經常使用的布爾運算符,假定變量 a 爲 10,變量 b 爲 20:
運算符 |
說明 |
舉例 |
! |
非運算,表達式爲 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。 |
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小於 100 且 $b 大於 15 : 返回 true"
else
echo "$a 小於 100 且 $b 大於 15 : 返回 false"
fi
邏輯運算符
如下介紹 Shell 的邏輯運算符,假定變量 a 爲 10,變量 b 爲 20:
運算符 |
說明 |
舉例 |
&& |
邏輯的 AND |
[[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| |
邏輯的 OR |
[[ $a -lt 100 || $b -gt 100 ]] 返回 true |
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
字符串運算符
下表列出了經常使用的字符串運算符,假定變量 a 爲 "abc",變量 b 爲 "efg":
運算符 |
說明 |
舉例 |
= |
檢測兩個字符串是否相等,相等返回 true。 |
[ $a = $b ] 返回 false。 |
!= |
檢測兩個字符串是否相等,不相等返回 true。 |
[ $a != $b ] 返回 true。 |
-z |
檢測字符串長度是否爲0,爲0返回 true。 |
[ -z $a ] 返回 false。 |
-n |
檢測字符串長度是否爲0,不爲0返回 true。 |
[ -n "$a" ] 返回 true。 |
str |
檢測字符串是否爲空,不爲空返回 true。 |
[ $a ] 返回 true。 |
if [ $a = $b ]
then
echo "$a = $b : a 等於 b"
else
echo "$a = $b: a 不等於 b"
fi
文件測試運算符
文件測試運算符用於檢測 Unix 文件的各類屬性。
屬性檢測描述以下:
操做符 |
說明 |
舉例 |
-b file |
檢測文件是不是塊設備文件,若是是,則返回 true。 |
[ -b $file ] 返回 false。 |
-c file |
檢測文件是不是字符設備文件,若是是,則返回 true。 |
[ -c $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。 |
file="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可讀"
else
echo "文件不可讀"
fi
Shell echo命令
用於字符串的輸出。命令格式:
echo string
1.顯示普通字符串:
echo "It is a test"
echo It is a test
2.顯示轉義字符
echo "\"It is a test\""
結果將是:
"It is a test"
雙引號也能夠省略
3.顯示變量
read 命令從標準輸入中讀取一行,並把輸入行的每一個字段的值指定給 shell 變量
#!/bin/sh
read name
echo "$name It is a test"
以上代碼保存爲 test.sh,name 接收標準輸入的變量,結果將是:
[root@www ~]# sh test.sh
OK #標準輸入
OK It is a test #輸出
4.顯示換行
echo -e "OK! \n" # -e 開啓轉義
echo "It is a test"
輸出結果:
OK!
It is a test
5.顯示不換行
#!/bin/sh
echo -e "OK! \c" # -e 開啓轉義 \c 不換行
echo "It is a test"
輸出結果:
OK! It is a test
6.顯示結果定向至文件
echo "It is a test" > myfile
7.原樣輸出字符串,不進行轉義或取變量(用單引號)
echo '$name\"'
輸出結果:
$name\"
8.顯示命令執行結果
echo `date`
注意: 這裏使用的是反引號 `, 而不是單引號 '。
結果將顯示當前日期
Thu Jul 24 10:08:46 CST 2014
Shell printf 命令
上一章節咱們學習了 Shell 的 echo 命令,本章節咱們來學習 Shell 的另外一個輸出命令 printf。
printf 的腳本比使用 echo 移植性好。
默認 printf 不會像 echo 自動添加換行符,咱們能夠手動添加 \n。
printf 命令的語法:
printf format-string [arguments...]
printf "%-10s %-8s %-4s\n" 姓名 性別 體重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 楊過 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
執行腳本,輸出結果以下所示:
姓名 性別 體重kg
郭靖 男 66.12
楊過 男 48.65
郭芙 女 47.99
# format-string爲雙引號
printf "%d %s\n" 1 "abc"
# 單引號與雙引號效果同樣
printf '%d %s\n' 1 "abc"
# 沒有引號也能夠輸出
printf %s abcdef
# 格式只指定了一個參數,但多出的參數仍然會按照該格式輸出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 若是沒有 arguments,那麼 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
執行腳本,輸出結果以下所示:
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
printf的轉義序列
序列 |
說明 |
\a |
警告字符,一般爲ASCII的BEL字符 |
\b |
後退 |
\c |
抑制(不顯示)輸出結果中任何結尾的換行字符(只在%b格式指示符控制下的參數字符串中有效) ,並且,任何留在參數裏的字符、任何接下來的參數以及任何留在格式字符串中的字符,都被忽略 |
\f |
換頁(formfeed) |
\n |
換行 |
\r |
回車(Carriage return) |
\t |
水平製表符 |
\v |
垂直製表符 |
\\ |
一個字面上的反斜槓字符 |
\ddd |
表示1到3位數八進制值的字符。僅在格式字符串中有效 |
\0ddd |
表示1到3位的八進制值字符 |
Shell test 命令
Shell中的 test 命令用於檢查某個條件是否成立,它能夠進行數值、字符和文件三個方面的測試。
數值測試
參數 |
說明 |
-eq |
等於則爲真 |
-ne |
不等於則爲真 |
-gt |
大於則爲真 |
-ge |
大於等於則爲真 |
-lt |
小於則爲真 |
-le |
小於等於則爲真 |
if test $[num1] -eq $[num2]
then
echo '兩個數相等!'
else
echo '兩個數不相等!'
fi
代碼中的 [] 執行基本的算數運算
字符串測試
參數 |
說明 |
= |
等於則爲真 |
!= |
不相等則爲真 |
-z 字符串 |
字符串的長度爲零則爲真 |
-n 字符串 |
字符串的長度不爲零則爲真 |
if test $num1 = $num2
then
echo '兩個字符串相等!'
else
echo '兩個字符串不相等!'
fi
文件測試
參數 |
說明 |
-e 文件名 |
若是文件存在則爲真 |
-r 文件名 |
若是文件存在且可讀則爲真 |
-w 文件名 |
若是文件存在且可寫則爲真 |
-x 文件名 |
若是文件存在且可執行則爲真 |
-s 文件名 |
若是文件存在且至少有一個字符則爲真 |
-d 文件名 |
若是文件存在且爲目錄則爲真 |
-f 文件名 |
若是文件存在且爲普通文件則爲真 |
-c 文件名 |
若是文件存在且爲字符型特殊文件則爲真 |
-b 文件名 |
若是文件存在且爲塊特殊文件則爲真 |
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
Shell 流程控制
sh的流程控制不可爲空.
if 語句語法格式:
if condition
then
command1
command2
...
commandN
fi
if else 語法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else 語法格式:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
for循環通常格式爲:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
while循環用於不斷執行一系列命令,也用於從輸入文件中讀取數據;命令一般爲測試條件。其格式爲:
while condition
do
command
done
無限循環語法格式:
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
until 循環執行一系列命令直至條件爲 true 時中止。與 while 循環在處理方式上恰好相反。
until condition
do
command
done
case語句爲多選擇語句。能夠用case語句匹配一個值與一個模式,若是匹配成功,執行相匹配的命令。case語句格式以下:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
break命令容許跳出全部循環(終止執行後面的全部循環)。
continue命令,僅僅跳出當前循環。