Shell編程

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 先減
! 邏輯求反
~ 位求反
** 冪運算
<< 左位移
>
右位移
& 位布爾和
&#124 位布爾或
&& 邏輯和
&#124&#124 邏輯或
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. 讀取參數

位置參數變量是標準的數字:0 1是第一個參數,2 9。

2. 抓取所有的數據

$*$@可以抓取命令行上的所有參數。但是$*是當作一個參數執行,而$@是對每個參數進行處理

3. 移動變量

shift 2:移動兩個位置

4. 處理選項

分離參數和選項(--

使用getopt命令:getopt optstring parameters,在腳本中使用格式:set – (getoptqab:cd" @”)

使用更高級的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命令來計劃執行作業
  1. at命令的格式

格式:

at [ -f filename ] time

at -f test.sh now

  1. 列出等待的作業

atq可以查看系統中等待的作業

  1. 刪除作業

arrm刪除等待的作業

2. 安排需要定期執行的腳本
  1. cron時間表

格式:

min hour dayofmonth month dayofweek command

  1. 構建cron時間表

crontb -l:列出時間表

  1. 瀏覽cron目錄

包括:hourly、daily、monthly、weekly

ls /etc/cron.*ly

  1. 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

說明:

  1. 一次從輸入中讀取一行數據

  2. 根據所提供的編輯器命令匹配數據

  3. 按照命令修改流中的數據

  4. 將新的數據輸出到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

  1. 執行多個命令格式:

sed -e ‘e/brown/green/;s/dog/cat/’ data.txt

  1. 從文件中讀取編輯器命令

sed -f file.sed data.txt

2. gawk程序
  1. 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!”}’

  1. 使用數據字段變量

$0:代表整個文本行

$1:代表文本行中的第1個數據字段

$2:代表文本行中的第2個數據字段

$n:代表文本行中的第n個數據字段

sde編輯器基礎

1. 更多的替換選項
  1. 替換標記

s/pattern/replacement/flags

flags:

  • 數字:將新文本替換第幾行模式匹配的地方

  • g:替換所有

  • p:原先行的內容要打印出來

  • w:file,將替換的結果寫到文件中

    1. 替換字符

/

2. 使用地址

行尋址(line addressing)

  • 以數字形式表示行區間

  • 用文本模式來過濾出行

格式:

[address] command

address{
command1
command2
command3
}

  1. 數字方式的行尋址

sed ‘2s/dog/cat’ data.txt

sed ‘2,3s/dog/cat’ data.txt

sed ‘2,$s/dog/cat’ data.txt

  1. 使用文本模式過濾器

格式:

/pattern/command

  1. 命令組合
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章