訊號處理 & expect免互動命令執行
阿新 • • 發佈:2020-09-01
目錄
一 訊號處理
# 1 什麼是訊號 由鍵盤組合鍵或者kill命令發出操作稱之為訊號 訊號是傳送給程序的,程序在收到訊號後會作出預設的響應 # 2 為何要在程序內處理訊號 程序在收到訊號後會有預設的響應, 如果我們想改變程序在接收到訊號後的反應,那麼需要在程序內捕捉訊號執行我們自定義的操作 # 3 主要的應用場景: 在程序內捕捉終止訊號,然後忽略掉,從而達到讓程序不受外界干擾正常執行完畢的效果 ps:不是所有的訊號都可以被捕捉,比如-9 3、如何處理訊號 trap "捕捉到訊號之後要執行的命令" 訊號 trap "" 訊號 # 如不指定執行資訊則當做不做處理 trap "" 訊號1 訊號2 訊號3 # 多個訊號都不做處理
trap訊號列表
訊號 | 說明 |
---|---|
HUP | 掛起,通常因終端掉線或使用者退出而引發 |
INT | 中斷,通常因按下Crtl+C組合健而引發 |
QUIT | 退出,通常因某些嚴重的執行錯誤而引發 |
TERM | 終止,通常在系統關機時傳送 |
TSTP | 停止程序的執行,但該訊號可以被處理和忽略,使用者健入SUSP字元時(通常是Ctrl-Z)發出這個訊號 |
ABRT | 中止,通常因某些嚴重的執行錯誤而引發 |
- 示例如
# 使用此方式執行指令碼,對鍵盤執行的ctrl+c ctrl+z等其他操作都不會進行操作,以往執行ctrl+c都是停止。 · 這裡主要實現對指令碼迴圈執行紅綠燈,並且此指令碼執行過程中不受下方訊號影響。 [root@tcy day07]# cat 3.sh #!/bin/bash trap "" INT QUIT HUP TERM TSTP # 當執行這些訊號都不會做任何操作 clear n=0 while : do [ $n -eq 0 ] && n=1 || n=0 if [ $n -eq 1 ];then echo -e "\033[31m 紅燈亮 \033[0m" else echo -e "\033[32m 綠燈亮 \033[0m" fi sleep 0.5 clear done
HUP訊號的處理:讓一個程序脫離當前會話視窗執行
nohup脫離父程序
-
(需將其終端關閉,才能將父程序改變為系統程序,否則為終端程序)
# 在終端2內 [root@tcy ~]# echo $$ 12479 [root@tcy ~]# nohup ping www.baidu.com & # 關閉終端2 # 在終端1內仍然可以看到程序(但其父程序為系統程序) [root@tcy ~]# ps -ef |grep [p]ing root 13169 1 0 18:58 ? 00:00:00 ping www.baidu.com
-
setsid(直接讓父程序為系統程序)
setsid ping www.baidu.com &
-
(程序 &) 直接讓父程序為系統程序
(ping www.tcy.com &) [root@db01 ~]# ps -ef|grep tcy root 8333 1 0 22:46 pts/1 00:00:00 ping www.tcy.com root 8360 8336 0 22:46 pts/2 00:00:00 grep --color=auto tcy
二 expect
expect介紹
在使用expect
時,基本上都是和以下四個命令打交道:
命令 | 作用 |
---|---|
spawn | 啟動新的程序 |
expect | 從程序接收字串 |
send | 用於向程序傳送字串 |
interact | 允許使用者互動 |
spawn
命令用來啟動新的程序,spawn
後的expect
和send
命令都是和使用spawn
啟動的新程序進行互動。expect
通常用來等待一個程序的反饋,我們根據程序的反饋,再使用send
命令傳送對應的互動命令。send
命令接收一個字串引數,並將該引數傳送到程序。interact
命令用的其實不是很多,一般情況下使用spawn
、expect
和send
和命令就可以很好的完成我們的任務;但在一些特殊場合下還是需要使用interact
命令的,interact
命令主要用於退出自動化,進入人工互動。比如我們使用spawn
、send
和expect
命令完成了ftp登陸主機,執行下載檔案任務,但是我們希望在檔案下載結束以後,仍然可以停留在ftp命令列狀態,以便手動的執行後續命令,此時使用interact
命令就可以很好的完成這個任務。
expect基本使用
# 前期需要安裝expect安裝包
[root@db01 day08]# yum install -y expect
# send指令提交方式(兩者都可對指令進行提交)
\n
\r
[root@tcy day07]# cat 4.sh
#!/usr/bin/expect # 這裡雖然是指令碼,但是需要指定直譯器為expect
spawn ssh [email protected] hostname # 執行程序操作指令
expect "yes/no" # 等待程序反饋,匹配yes/no的指令
send "yes\r" # 根據expect匹配的指令進行操作,也就是直接幫助yes提交
expect "assword" # 繼續等待程序反饋,屁屁額assword指令
send "1\n" # 根據匹配的指令進行1操作,這裡也就是我的密碼
expect eof # 結束互動指令
# 總結:
這種操作存在弊端,只適用於第一次連線,如第二次進行ssh連線,可忽略yes步驟,直接輸入密碼即可,expect比較愚蠢,
不會只能匹配,而是在第二次連線時當需要輸入密碼,直接也將第一次匹配的yes直接傳送,也就導致了後續的報錯。
所以這裡為了解決此問題,可參考expect一問一答中的案例操作。
強調:我們此時編寫的是expect指令碼,不要用sh 4.sh執行,可以./4.sh執行,也可以expect 4.sh執行
expect 一問一答(推薦使用)
# 這裡會根據程序指令自動匹配,所以需要將操作匹配指令寫入同一個expect中進行處理。
#!/usr/bin/expect
spawn ssh [email protected] hostname
expect {
"yes/no" {send "yes\n";exp_continue}
"*assword" {send "1\n";}
}
expect eof
遠端登入主機執行多條命令
# 可免互動式登入主機執行多條語句,注意,這裡都是expect語句,不能按照shell語句方式執行
[root@tcy day07]# cat 6.sh
#!/usr/bin/expect
spawn ssh [email protected]
expect {
"yes/no" {send "yes\n";exp_continue}
"*assword" {send "1\n";}
}
expect {
"#" {send "ls\n"} # 這裡為匹配#互動式指令,到匹配到就執行ls命令
}
expect {
"*root*" {send "pwd\n"} # 這裡為匹配root互動式指令,匹配到就執行pwd指令
}
expect {
"#" {send "exit\n"} # 這裡為匹配# 指令,匹配到就執行exit指令,相當於回到自己的終端
}
expect eof # 結束互動式操作,但還在遠端的終端中,超時才會自動退出
interact(瞭解)
[root@tcy day07]# cat 7.sh
#!/usr/bin/expect
spawn ssh [email protected]
expect {
"yes/no" {send "yes\n";exp_continue}
"*assword" {send "1\n";}
}
expect {
"*tcy*" {send "ls\n"}
}
expect {
"*tcy*" {send "pwd\n"}
}
interact # 執行完以上指令,不進行超時退出,任然停留在遠端終端中
expect eof
在expect指令碼中定義變數
# 使用的並不是bash直譯器,所以需要expect自身語法。
#!/usr/bin/expect
set user "root" # 類似於bash的定義變數user=root
set pass "1"
set ip "127.0.0.1"
set cmd "hostname"
spawn ssh $user@$ip $cmd # 呼叫上方定義變數開啟程序
expect {
"yes/no" {send "yes\n";exp_continue}
"*assword" {send "$pass\n";}
}
expect eof
把expect引入shell指令碼(推薦使用)
# 單學expect較為複雜,可將expect引入bash中。
#!/bin/bash # 使用bash直譯器
user="root" # 使用bash的方式定義變數
pass="1"
ip="127.0.0.1"
cmd="hostname"
expect << EOF # 引expect在bash中也是一個命令,所以將其
spawn ssh $user@$ip $cmd # 內容放入一個內容體當中
expect {
"yes/no" {send "yes\n";exp_continue}
"*assword" {send "$pass\n";}
}
expect eof
EOF
echo "success!!!"