shell編程
shell定義
Shell 腳本是一個包含一連串 shell 命令語句的文本文件,通常以 .sh 為擴展名,可被當作一個獨立的程序來執行,從而實現數據的批量處理。其通常由 shell header (shebang) 和 body (命令語句) 兩部分組成。
Shell header
#!/bin/bash
set -e
set -u
!/bin/bash → shebang,表示執行該腳本所用的解釋器。整個腳本必須以這行開始,且必須放在腳本的開頭。
set -e (可選) → 如果任何語句的執行結果不是true則退出腳本 (遇到錯誤立即終止腳本) ,從而可以及時地修改腳本而大大地提高工作效率。
如果使用 set +e 則表示遇到錯誤報錯但繼續執行后續腳本。
set -u (可選) → 如果使用未定義的變量則報錯并退出腳本。
Body
代碼的主體部分描述 “需要做什么,如何去做”。例如定義變量,列出一系列需要執行的命令等,shell 會按照我們所寫的順序依次執行各個命令。當然,我們可以用#來做注釋,來增加復雜代碼的可讀性。
echo "Hello world!" #此處為注釋,不會顯示在輸出結果中
echo "This is my first shell script!"
path=$HOME
echo "List the content of the path $path"
echo "Contents:"
ls -l $path
如何執行 shell 腳本
直接用 sh 或 bash 命令執行腳本,如:
$ bash MyFirstShellScript.sh
$ sh ./MyFirstShellScript.sh
$ sh /path/to/script/MyFirstShellScript.sh
賦予腳本可執行權限,直接執行腳本,如:
$ chmod u+x MyFirstShellScript
$ chmod 755 MyFirstShellScript
$ ./MyFirstShellScript
$ /path/to/script/MyFirstShellScript.sh
Shell 變量
shell 變量定義
Shell 變量可以存儲一定的信息 (輸入文件,參數的值,輸入文件目錄,輸出結果目錄和),從而在后續的命令中對這些信息進行處理。Shell 變量的值實際上都是字符串(沒有定義的變量默認是一個空字符串。Shell 變量可以不需要任何聲明而直接定義,變量名由字母、數字和下劃線組成,大小寫敏感;并且定義變量時等號兩邊不能有空格,否則會被認為是命令。在變量名前加 $ 來獲取變量的值。
shell 變量種類
- 系統變量:由操作系統創建,如:$PATH, $HOME, $BASH 等。
- 自定義變量:由用戶創建:如上例中的 $path。
$ echo $HOME
/root
$ echo $BASH
/bin/bash
$ path=$HOME
$ echo $path
/root
命令替換
使用$() 或 `` 來實現命令替換,即執行一個 shell 命令然后把輸出結果存到一個變量中。使用方式:var=$(command) 或 var=command
。
$ echo "Today is $(date "+%Y-%m-%d")"
Today is 2017-04-16
$ path=$HOME
$ command_output=`ls $HOME`
$ echo $command_output
Desktop Documents Downloads Music MyFirstShellScript.sh Pictures Public Videos
${} 的高級應用:取路徑、文件名、后綴、字符串和替換
規律
#是從左面開始匹配
%是從右面開始匹配
使用一個符號 (# 或 %) 是最小匹配
使用兩個符號 (## 或 %%) 是最大匹配
* 用來去掉不需要的字符
可以自己指定分割符號與 #, % 和 * 配合來決定取哪部分來替換
可以自己指定起始位置來決定提取哪部分字符串
可以使用 /str1/str2 來替換特定字符串
$ var=/home/username/data/test.txt.bac
$ echo ${var}
/home/username/data/test.txt.bac
$ echo ${var#*/}
#去掉第一個 / 及其左邊的字符串
home/username/data/test.txt.bac
$ echo ${var##*/}
#去掉最后一個 / 及其左邊的字符串
test.txt.bac
$ echo ${var%/*}
#去掉最后一個 / 及其右邊的字符串
/home/username/data
$ echo ${var%%/*}
#去掉第一個 / 及其右邊的字符串 (輸出結果為空)
$ echo ${var#*.}
#去掉第一個 . 及其左邊的字符串
txt.bac
$ echo ${var##*.}
#去掉最后一個 . 及其左邊的字符串
bac
$ echo ${var%.*}
#去掉最后一個 . 及其右邊的字符串
/home/username/data/test.txt
$ echo ${var%%.*}
#去掉第一個 . 及其右邊的字符串
/home/username/data/test
$ echo ${var:0:5}
#取第0位后的5個字節
/home
$ echo ${var:5:9}
#取第5位后的9個字節
/username
$ echo ${var/username/cat}
#將 username 替換為 cat
/home/cat/data/test.txt.bac
$ echo ${#var}
#取變量的長度
引用
引用是指用引用符號將字符串引起來,以防其中的特殊字符被 shell 解釋為其它含義。我們可以通過引用來控制‘命令替換’或把含有空格 (或其它特殊字符) 的字符串做為一個整體進行參數傳遞。
Shell 中三種常見的引用形式:
' ' (單引號) 所有字符保持原義但字符串中不能出現單引號本身 (全引用)
z 除 $, ` 和 \ 以外的所有字符保持原義 (部分引用)
\ (反斜線) 轉義字符,使接下來的一個字符保持原義
單引號和雙引號的區別:
在引用內容為純文本時,二者沒有本質差別。
如果想要獲取變量的值時,則需要使用雙引號。
$ test="world"
$ echo "Hello $test"
Hello World
$ echo 'Hello $test'
Hello $test
轉義
在某些情況下,我們需要保留特殊字符的原義,這時就需要用 \ 來轉義。舉個例子:
$ var="Hello world"
$ echo "The content of variable '\$var' is \"$var\""
The content of variable '$var' is "Hello world"
Shell 腳本中的參數傳遞
Shell 腳本可以從命令行獲取參數,這些參數被存入變量 $1, $2, $3 ... 中,這些變量被稱為特殊變量。
特殊變量 含義
$# 從命令行傳遞給腳本的參數個數
$0 當前執行腳本的名字
$n 從命令行傳遞給腳本的參數,從左到右被存入變量:$1, $2, $3 ... $9
$* 從命令行傳遞給腳本的所有參數
$@ 從命令行傳遞給腳本的所有參數
$$ 當前 shell 進程的 PID
$? 上一個執行命令的返回值
#!/bin/bash
set -e
set -u
echo "number of arguments: $#"
echo "script name is: $0"
echo "first argument is: $1"
echo "second argument is: $2"
echo "all arguments are: $*"
echo "all arguments are: $@"
echo "process number of the current process is: $$"
echo "exit value of the last command executed: $?"
執行腳本
sh test.sh hello world
顯示結果
number of arguments: 2
script name is: test.sh
first argument is: hello
second argument is: world
all arguments are: hello world
all arguments are: hello world
process number of the current process is: 106836
exit value of the last command executed: 0