shell程式設計入門基礎
shell 程式設計入門
Shell 環境
Shell 程式設計跟 java、php 程式設計一樣,只要有一個能編寫程式碼的文字編輯器和一個能解釋執行的指令碼直譯器就可以了。
Linux 的 Shell 種類眾多,常見的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
第一個shell指令碼
開啟文字編輯器(可以使用 vi/vim 命令來建立檔案),新建一個檔案 test.sh,副檔名為 sh(sh代表shell),副檔名並不影響指令碼執行,見名知意就好,如果你用 php 寫 shell 指令碼,副檔名就用 php 好了
#!/bin/bash
echo "Hello World !"
/bin/pwd
#!
是一個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種 Shell。
echo
命令用於向視窗輸出文字
可以在sh
檔案中寫諸如pwd、ls 這樣的命令,使用命令的時候儘量使用覺得路徑
命令一般兩個位置:
/bin
/usr/bin
1.1 執行 Shell 指令碼有兩種方法
- 作為可執行程式
chmod +x ./test.sh #使指令碼具有執行許可權。 ll 檢視是否有執行許可權,沒有則新增(chmod +x)
./test.sh #執行指令碼
注意,一定要寫成 ./test.sh
,而不是 PATH
裡尋找有沒有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 裡,你的當前目錄通常不在 PATH 裡,所以寫成 test.sh 是會找不到命令的,要用 ./test.sh
告訴系統說,就在當前目錄找
- 作為直譯器引數
直接執行直譯器,其引數就是 shell 指令碼的檔名
/bin/sh test.sh
# 或者簡化 sh.test.sh 也可以
1.2 shell 小案例
#!/bin/sh
# 引數 %F 格式化日期; >> 表示重定向追加到 ex.info中
/bin/date +%F >> /home/uzong/ex.info
echo "disk info" >> /home/uzong/ex.info
echo >> /home/uzong/ex.info
# 將磁碟情況列印
/bin/df -h >> /home/uzong/ex.info
echo "online users:" >> /home/uzong/ex.info
#輸出使用者資訊。 使用 管道 | 過濾,引數 -v 排查。
/usr/bin/who | /bin/grep -v root >> /home/uzong/ex.info
echo "Memory info" >> /home/uzong/ex.info
# free -m 記憶體使用情況
/usr/bin/free -m >> /home/uzong/ex.info
echo >> /home/uzong/ex.info
#vim root
/usr/bin/wall < /home/uzong/ex.info && /bin/rm /home/uzong/ex.info
1.3 shell 變數
定義變數時,變數名不加美元符號
your_name="runoob.com"
echo $your_name
echo ${your_name}
your_name="alibaba"
#第二次賦值的時候不能寫$your_name="alibaba",使用變數的時候才加美元符($)
#變數名外面的花括號是可選的,加不加都行,加花括號是為了幫助直譯器識別變數的邊界
變數名長度沒有限制,在使用變數值是,要在變數名前加上字首“$”
。一般變數使用大寫字母表示,並且全是英文字母開頭,賦值符號“=”兩邊沒有空格
注意: 變數名和等號之間不能有空格
變數是shell傳遞資料的一種方法,用來代表每個取值的符號名。
shell
有兩類變數,臨時變數和永久變數
臨時變數是shell程式內部定義的,其使用範圍僅限於定義它的程式,對其他程式不可見。包括:使用者自定義變數、位置變數。永久變數是環境變數,其不隨shell指令碼的執行結果而消失。
例如:永久變數
可以將一個命令的執行結果賦值給變數,但是需要使用命令替換符號。注意單引號和雙引號的區別,雙引號是會把裡面的變數值進行輸出,單引號是會把內容原封不動輸出,不會識別裡面的變數。
- 使用
set
命令檢視所有變數。 - 使用
unset
命令刪除指定的變數
案例:
#!/bin/bash
#使用 readonly 命令可以將變數定義為只讀變數,只讀變數的值不能被改變
myUrl="http://www.google.com"
readonly myUrl
myUrl="http://www.runoob.com"
#執行指令碼:/bin/sh: NAME: This variable is read only.
1.4 佔位變數
位置變數:ls -l file1 file2 file3 …(n範圍=1~9)在程式碼中使用$1-9進行代替。 案例:
#!/bin/sh
DATE=`/bin/date +%Y%m%d`
echo "today is $DATE"
# 佔位變數,使用$1-$9 代替。
/bin/ls -l $1
/bin/ls -l $2
/bin/ls -l $3
執行該指令碼:
1.5 特殊變數
$*
這個程式的所有引數
$#
這個程式的引數個數
$$
這個程式的PID
$!
執行上一個後臺命令的PID
$?
執行上一個命令的返回值
$(0-9)
顯示位置變數
1.6 read鍵盤錄入
從鍵盤錄入資料,賦值給變數
-x
跟蹤執行情況的作用。
1.7 expr命令,對整數進行運算。
注意:
expr
的運算必須用空格隔開\*
表示轉義符- 先算乘除後算加減,如果要優先運算,則需要加命令替換符
- 也可以對變數進行運算操作
運算子 | 說明 | 舉例 |
---|---|---|
-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 |
案例:
1.8 test 測試命令
在shell指令碼中做測試判斷
test -d file 知道檔案是否是目錄
test -f file 檔案是否為常規檔案
test -x file 檔案是否是可執行檔案
test -r file 檔案是否可讀
test -w file 檔案是否可寫
1.9 if 語句
語法格式 if test -d $1 then ... elif then .... else ... fi
變數測試語句可以用簡化格式:[]
,比如test -d $1
等價於["空格" -d $1 "空格" ]
(注意空格)
案例: 判斷一個入參是否為資料夾
if test -d $1 then ... elif then .... else ... fi
1.10 case
語法格式:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
案例:
1.11 while
語法格式:
while condition
do
command
done
案例:
1.12 break / continue
結束和繼續:
1.13 布林運算子 和 邏輯運算子
布林運算子
運算子 | 說明 | 舉例 |
---|---|---|
! | 非運算,表示式為 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。 |
邏輯運算子
運算子 | 說明 | 舉例 |
---|---|---|
&& |
邏輯的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| |
邏輯的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
案例
1.14 for 迴圈
這個語法用的不多。
for...done
語句格式
for 變數 in 名字表表
do
命令列表
done
案例:
1.15 select
語法用的不多
格式:
select 變數 in 列表
do
cmd...
done
案例:
二、函式
# 格式如下
[ function ] funname [()]
{
action;
[return int;]
}
2.1 不帶引數和返回值
2.2 有入參
在Shell中,呼叫函式時可以向其傳遞引數。在函式體內部,通過 $n 的形式來獲取引數的值,例如,$1表示第一個引數,$2表示第二個引數…
注意,$10
不能獲取第十個引數,獲取第十個引數需要${10}
。當n>=10
時,需要使用${n}
來獲取引數
2.3 返回值
引數處理 說明 $# 傳遞到指令碼的引數個數 $* 以一個單字串顯示所有向指令碼傳遞的引數 $$ 指令碼執行的當前程序ID號 $! 後臺執行的最後一個程序的ID號 *相同,但是使用時加引號,並在引號中返回每個引數。 $- 顯示Shell使用的當前選項,與set命令功能相同。 $? 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。
三、陣列
Shell 陣列用括號來表示,元素用"空格"符號分割開,語法格式如下:
#Shell 陣列用括號來表示,元素用"空格"符號分割開
array_name=(value1 ... valuen)
# 或者使用下標的方式
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
讀取陣列元素值的一般格式是
${array_name[index]}
案例:
四、Shell 輸入/輸出重定向
4.1 /dev/null 檔案
如果希望執行某個命令,但又不希望在螢幕上顯示輸出結果,那麼可以將輸出重定向到/dev/null
:
$ command > /dev/null
/dev/null 是一個特殊的檔案,寫入到它的內容都會被丟棄;如果嘗試從該檔案讀取內容,那麼什麼也讀不到。但是 /dev/null 檔案非常有用,將命令的輸出重定向到它,會起到"禁止輸出"的效果。 如果希望遮蔽 stdout 和 stderr,可以這樣寫:
$ command > /dev/null 2>&1
五、Shell 檔案包含
和其他語言一樣,Shell 也可以包含外部指令碼。這樣可以很方便的封裝一些公用的程式碼作為一個獨立的檔案。
#Shell 檔案包含的語法格式如下:
. filename # 注意點號(.)和檔名中間有一空格
或
source filename