shell腳本編程
構建基本腳本
註釋格式
#!/bin/sh
# FILENAME: test_shell
# AUTHOR: Javy
# Email: [email protected]
# PURPOSE: Demonstration of comment style
# HISTORY: 1 May, 2018 Created
# 5 May, 2018 Modified to show mods
顯示消息
echo This is a test
說明:
- -n:輸出在同一行
使用變量
1. 環境變量
- set 顯示所有的當前環境變量列表
例如:
#!bin/bash
# display user information from the system.
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME
2. 用戶變量
3. 命令替換
反引號字符( `)
$()格式
#!bin/bash
testing=$(date)
重定向輸入和輸出
1. 輸出重定向
command > outputfile
2. 輸入重定向
command < outputfile
管道
執行數學運算
1. expr命令
expr 1 + 5
2. 使用方括號
$[ operation ]
3. 浮點解決方案
- bc的基本用法
bc -q
quit
2. 在腳本中使用bc
variable=$(echo "options; expression" | bc)
說明:
options:設置變量,允許多個變量可以用分號隔開。
expression:定義bc執行的數學表達式。
variable=$(bc << EOF
options
statements
expression
EOF
)
退出腳本
1. 查看退出狀態碼
$?
可查看退出狀態
說明:
狀態碼 | 描述 |
---|---|
0 | 命令成功結束 |
1 | 一般性未知錯誤 |
2 | 不適合的shell執行命令 |
126 | 命令不可執行 |
127 | 沒找到命令 |
128 | 無效的退出參數 |
128+x | 與Linux信息x相關的嚴重錯誤 |
130 | 通過Ctrl+C終止的命令 |
255 | 正常範圍之外的退出狀態碼 |
2. exit命令
可以指定退出碼exit num
,num表示0~255之間的數,如果大於將以取模的形式返回。
使用結構化命令
使用if-then語句
格式:
if command then
commands
fi
說明:
if後面的command是一個命令,如果命令退出代碼是0,then部分就會被允許,如果是其他碼then部分不會被執行。
使用if-then-else語句
格式:
if command then
commands
else
commands
fi
嵌套if
test命令
test condition
if test condition then
commands
fi
也可以寫爲:
if [ condition ] then
commands
fi
test命令可以判斷的三類條件:
數值比較
字符串比較
文件比較
1. 數值比較
比較 | 描述 | 比較命令說明 |
---|---|---|
n1 -eq n2 | n1是否與n2相等 | -equal |
n1 -ge n2 | n1是否大於或等於n2 | -(greater and equal) |
n1 -gt n2 | n1是否大於n2 | -(greater than) |
n1 -le n2 | n1是否小於或等於n2 | -(less and equal) |
n1 -lt n2 | n1是否小於n2 | -(less than) |
n1 -ne n2 | n1是否不等於n2 | -(not equal) |
2. 字符串比較
比較 | 描述 |
---|---|
str1 = str2 | str1是否與str2相同 |
str1 != str2 | str1是否與str2不同 |
str1 < str2 | str1是否比str2小 |
str1 > str2 | str1是否比str2大 |
-n str1 | str1的長度是否非0 |
-z str1 | str1的長度是否爲0 |
注: 在使用<
和>
是需要進行轉義,就想這樣\<
和\>
。
3. 文件比較
比較 | 描述 |
---|---|
-d file | file是否存在並是一個目錄 |
-e file | file是否存在 |
-f file | file是否存在並是一個文件 |
-r file | file是否存在並可讀 |
-s file | file是否存在並非空 |
-w file | file是否存在並可寫 |
-x file | file是否存在並可執行 |
-o file | file是否存在並屬當前用戶所有 |
-G file | file是否存在並默認與當前用戶相同 |
file1 -nt file2 | file1是否比file2新 |
file1 -ot file2 | file1是否比file2舊 |
複合條件測試
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
if-then的高級特性
用於數學表達式的雙括號
用於高級字符串處理功能的雙方括號
1. 使用雙括號
格式:
(( expression ))
表達式參數符號說明:
符號 | 描述 |
---|---|
val++ | 後增 |
val– | 後減 |
++val | 先增 |
–val | 先減 |
! | 邏輯求反 |
~ | 位求反 |
** | 冪運算 |
<< | 左位移 |
> |
右位移 |
& | 位布爾和 |
| | 位布爾或 |
&& | 邏輯和 |
|| | 邏輯或 |
2. 使用雙方括號
[[ expression ]]
case命令
格式:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
更多的結構化命令
for命令
格式:
for var in list
do
commands
done
C語言風格的for命令
格式:
for (( variable assignment ; condition ; iteration process ))
使用多個變量:
for (( a=1, b=10; a <= 10; a++, b-- )); do
#statements
done
while命令
格式:
while [ command ]
do
other commands
done
until命令
格式:
until [ command ]
do
other commands
done
嵌套循環
循環處理文件數據
控制循環
1. break命令
跳出外部循環:break n (默認n=1)
2. continue命令
處理循環的輸出
for (( i = 0; i < 10; i++ )); do
#statements
done > outputfile.txt
最後的結果使用定向輸出:>
處理用戶輸入
命令行參數
1. 讀取參數
位置參數變量是標準的數字: 1是第一個參數, 9。
2. 抓取所有的數據
$*
和$@
可以抓取命令行上的所有參數。但是$*
是當作一個參數執行,而$@
是對每個參數進行處理
3. 移動變量
shift 2
:移動兩個位置
4. 處理選項
分離參數和選項(--
)
使用getopt
命令:getopt optstring parameters,在腳本中使用格式:set – @”)
使用更高級的getopts
:getopt optstring variable
4. 獲得用戶輸入
read
echo -n "Enter your name: "
read name
echo "Hello $name, welcome to my program. "
read -p
read -p "Enter your age: " age
days=$[ $age * 365 ]
echo "That makes you over $days days old! "
2. 超時
read -t
if read -t 5 -p "Please Enter your name: " name
then
echo "Hello $name, welcome to my program. "
else
echo
echo "Sorry, too slow!"
fi
read -n1
read -n1 -p "Do you want to continue [Y/N]?: " answer
case $answer in
Y | y) echo
echo "fine, continue on...";;
N | n) echo
echo "Ok, goodbye"
exit;;
esac
echo "This is the end of the script"
3. 隱藏方式讀取
read -s
read -s "Enter your password: " pass
echo
echo "Is your password really $pass? "
4. 從文件中讀取
Count=1
cat test | while read line
do
echo "Line $Count: $Line"
Count=$[ $Count + 1 ]
done
echo "Finished processing the file"
呈現數據
理解輸入和輸出
1. 標準文件描述符
文件描述符 | 縮寫 | 描述 |
---|---|---|
0 | STDIN | 標準輸入 |
1 | STDOUT | 標準輸出 |
2 | STDERR | 標準錯誤 |
2. 重定向錯誤
ls -al test 2> test1 1> test2
ls -al test &>test1
在腳本中重定向輸出
1. 臨時重定向
2. 永久重定向
exec 1>testout
echo "...."
echo "......."
在腳本中重定向輸入
exec 0< testfile
創建自己的重定向
1. 關閉文件描述符
exec 3>&-
列出打的開文件描述符
lsof
記錄消息
tee filename 默認會覆蓋
tee -a filename 實現追加
實例
#!bin/bash
# read file and create INSERT statements for MySQL
outputfile='member.sql'
IFS=','
while read lname fname address city state zip
do
cat \>> $outputfile \<< EOF
INSEART INTO members (lname, fname, address, city, state, zip) VALUES ('$lname', '$fname', '$address', '$city', '$state', '$zip');
EOF
done < S{1}
控制腳本
處理信號
1. 重溫Linux信號
信號 | 值 | 描述 |
---|---|---|
1 | SIGHUP | 掛起進程 |
2 | SIGINT | 終止進程 |
3 | SIGQUIT | 停止進程 |
9 | SIGKILL | 無條件終止進程 |
15 | SIGTRERM | 儘可能終止進程 |
17 | SIGSTOP | 無條件停止進程但不是終止進程 |
18 | SIGTSTP | 停止或暫停進程,但不終止進程 |
19 | SIGCONT | 繼續運行停止的進程 |
2. 生成信號
- 中斷進程
Ctrl + C
- 暫停進程
Ctrl + Z
3. 捕獲信號
格式:
tarp commands signals
4. 捕獲腳本退出
tarp commands signals EXIT
5. 修改或移除捕獲
以後臺模式運行腳本
1. 以後臺運行腳本
./test.sh &
2. 運行多個後臺作業
在非控制檯下運行腳本
格式:
nohup ./test.sh &
作業控制
1. 查看作業
jobs
參數說明:
參數 | 描述 |
---|---|
-l | 列出進程的PID以及作業號 |
-n | 只列出上次shell發出的通知後改變了狀態的作業 |
-p | 只列出作業的PID |
-r | 只列出運行中的作業 |
-s | 只列出已停止的作業 |
2. 重啓停止的作業
後臺模式運行:bg id
前臺模式運行:fg id
調整謙讓度
1. nice命令
nice -n:指定新的優先級級別
2. renice命令
renice -n 10 -p 5055
定時運行作業
1. 用at命令來計劃執行作業
- at命令的格式
格式:
at [ -f filename ] time
at -f test.sh now
- 列出等待的作業
atq可以查看系統中等待的作業
- 刪除作業
arrm刪除等待的作業
2. 安排需要定期執行的腳本
- cron時間表
格式:
min hour dayofmonth month dayofweek command
- 構建cron時間表
crontb -l:列出時間表
- 瀏覽cron目錄
包括:hourly、daily、monthly、weekly
ls /etc/cron.*ly
- anacron程序
格式:
period delay identifier command
高級shell腳本編程
創建函數
基本的腳本函數
1. 創建函數
function name {
commands
}
name() {
commands
}
2. 使用函數
返回值
- 默認退出狀態碼
$?
- 使用return命令
注意: 函數一結束就取返回值;退出狀態碼必須是0~255。
- 使用函數輸出
在函數中使用變量
局部變量:local temp
數組變量和函數
圖形化桌面環境中的腳本編程
初識sed和gawk
文本處理
1. sed編輯器
sed:stream editor
說明:
一次從輸入中讀取一行數據
根據所提供的編輯器命令匹配數據
按照命令修改流中的數據
將新的數據輸出到STDOUT。
格式:
sed options script file
選項:
選項 | 描述 |
---|---|
-e script | 在處理輸入時,將script中指定的命令添加到已有的命令中 |
-f file | 在處理輸入時,將file中指定的命令添加到已有的命令中 |
-n | 不產生命令輸出,使用print命令完成輸出 |
1. 格式:
sed ‘s/test/big test/’
例如:
echo “this is a test” | sed ‘s/test/big test/’
sed ‘s/dog/cat/’ data.txt
- 執行多個命令格式:
sed -e ‘e/brown/green/;s/dog/cat/’ data.txt
- 從文件中讀取編輯器命令
sed -f file.sed data.txt
2. gawk程序
- gawk命令格式
gawk options program file
可用選項:
選項 | 描述 |
---|---|
-F fs | 指定行中劃分數據字段的字段分隔符 |
-f file | 從指定的文件中讀取程序 |
-v var=value | 定義gawk程序中的一個變量及其默認值 |
-mf N | 指定要處理的數據文件中的最大字段數 |
-mr N | 指定數據文件中的最大數據行數 |
-W keyword | 指定gawk的兼容模式或警告等級 |
2. 從命令行讀取程序腳本
graw ‘{print “Hello World!”}’
- 使用數據字段變量
$0:代表整個文本行
$1:代表文本行中的第1個數據字段
$2:代表文本行中的第2個數據字段
$n:代表文本行中的第n個數據字段
sde編輯器基礎
1. 更多的替換選項
- 替換標記
s/pattern/replacement/flags
flags:
數字:將新文本替換第幾行模式匹配的地方
g:替換所有
p:原先行的內容要打印出來
w:file,將替換的結果寫到文件中
- 替換字符
/
2. 使用地址
行尋址(line addressing)
以數字形式表示行區間
用文本模式來過濾出行
格式:
[address] command
address{
command1
command2
command3
}
- 數字方式的行尋址
sed ‘2s/dog/cat’ data.txt
sed ‘2,3s/dog/cat’ data.txt
sed ‘2,$s/dog/cat’ data.txt
- 使用文本模式過濾器
格式:
/pattern/command
- 命令組合
3. 刪除行
sed ‘d’ data.txt
4. 插入和附加文本
- insert命令i
- append命令a
格式:
sed ‘[address]command\new line’
舉例:
sed ‘i\Test line 1’
sed ‘a\test line 1’
5. 修改行
sed ‘3c\t xxxx’ data.txt
轉換命令
[address]y/inchars/outchars