shell擴充套件——免互動指令碼

知無涯學無盡發表於2020-10-19

一、Here Document 免互動

使用工/o重定向的方式將命令列表提供給互動式程式,標準輸入的一種替代品

語法格式:

命令<<標記
…… #標記之間是傳入內容
……
標記

注意事項:

  • 標記可以使用任意合法字元(通常為EOF)
  • 結尾的標記一定要頂格寫,前面不能有任何字元
  • 結尾的標記後面也不能有任何字元(包括空格)
  • 開頭標記前後的空格會被省略掉

示例

1.免互動方式實現對行數的統計,將要統計的內容置於標記"EOF"之間,直接將內容傳給wc -l來統計

[root@localhost ~]# wc -l <<eof
> line 1
> line2
> line3
> line4
> eof
4      //輸出結果4行

2.通過passwd給使用者設定密碼

[root@localhost ~]# useradd lisi
[root@localhost ~]# passwd lisi <<eof
> abc123
> abc123
> eof

3.整體賦值給變數

#/bin/bash
I="i'm smart"
m=$(cat <<eof
I am cool
$I      //在內部呼叫變數I
eof
)
echo $m
[root@localhost ~]# ./test.sh 
I am cool i'm smart

4.支援變數的替換

[root@localhost ~]# vi test.sh
#/bin/bash
I="i'm smart"
F=test.txt
cat > $F <<eof      //相當於將cat檢視到的內容重定向到test.txt中
I am cool and $I
eof
[root@localhost ~]# ./test.sh 
[root@localhost ~]# cat test.txt 
I am cool and i'm smart

5.關閉變數替換的功能,對標記加單引號,即可關閉變數替換

[root@localhost ~]# vi test.sh 
#/bin/bash
I="i'm smart"
F=test.txt
cat > $F <<eof      //相當於將cat檢視到的內容重定向到test.txt中
I am cool and $I
eof
[root@localhost ~]# ./test.sh 
[root@localhost ~]# cat test.txt     //變數不能在被呼叫
I am cool and $I

6.多行註釋,":”開頭的Here Document標記內容不會被執行

-----------------------使用:eof註釋前效果-----------------------------------------
#/bin/bash
M=$(cat <<eof
I am cool
eof
cat <<eof
I'm smart
eof
)
echo $M

[root@localhost ~]# ./test.sh 
I am cool I'm smart
-----------------------使用:eof註釋後效果-----------------------------------------
#/bin/bash
M=$(cat <<eof
I am cool
eof
cat :<<eof
I'm smart
eof
)
echo $M
[root@localhost ~]# ./test.sh 
cat: :: 沒有那個檔案或目錄
I am cool

二、Expect 免互動

Expect是建立在tcl語言基礎上的一個工具,常被用於進行自動化控制和測試,解決shell指令碼中互動相關的問題
因此我們需要檢視是否已經安裝tcl語言環境及expect程式

[root@localhost ~]# rpm -q expect
未安裝軟體包 expect 
[root@localhost ~]# rpm -q tcl
未安裝軟體包 tcl 
[root@localhost yum.repos.d]# yum -y install expect
[root@localhost yum.repos.d]# yum -y install tcl

基本命令:

(1)指令碼直譯器
expect指令碼中首先引入檔案,表明使用的是哪一個shell。
.!/usr/bin/expect
(2) spawn
spawn後面通常跟一個命令,表示開啟一個會話、啟動程式,並跟蹤後續互動資訊。
例:spawn passwd root
( 3) expect
判斷上次輸出結果中是否包含指定的字串,如果有則立即返回,否則就等待超時時間後返回;只能捕捉由tspawm啟動的程式的輸出,用於接收命令執行後的輸出,然後和期望的字串匹配
( 4) send
向程式傳送字串,用於模擬使用者的輸入;該命令不能自動回車換行,一般要加\r(回車),有三種方式
例:

casel="密碼"
respond="abc1234""
-----------------------------------方式1-----------------------------------------------------
expect "$casei"{ send "srespond1\r"}
-----------------------------------方式2-----------------------------------------------------
expect "$casel"
send "$response1\r"
-----------------------------------方式3------------------------------------------------------
expect {
"$case1" { send "$response1\r"}
"$case2" { send "$response2\r"}
"$case3" { send "$response3\r"}
}

(5)結束符

  • expect eof
    等待執行結束,退回到原使用者,spawn對應
    expect指令碼預設的是等待10s,當執行完ls命令後,預設停留10s後,自動切回了原使用者
  • interact
    執行完成後保持互動狀態,把控制權交給控制檯,會停留在目標終端而不會退回到原終端,這個時候就可以手工操作了,interact後的命令不起作用,比如interact後新增exit,並不會退出root使用者。而如果沒有interact則登入完成後會退出,而不是留在遠端終端上。使用interact會保持在終端而不會退回到原終端,比如切換到rot使用者,會一直在root使用者狀態下,比如ish到另一伺服器,會一直在目標伺服器終端,而不會切回的原伺服器。
  • 注意:expect eof 與interact只能二選一。

(6) set
expect預設的超時時間是10秒,通過set命令可以設定會話超時時間,若不限制超時時間則應設定為-1。
例:set timeout 30
(7) exp _continue
exp_continue表示允許expect繼續向下執行指令。
例:

expect
{
"請輸入密碼”{ send "abc123";exp_continue}
"再次輸入密碼”{send "abc123";exp_continue }
"清再再次輸入密碼”{send "abc123"}
)

8 send user
send user―麥示回顯命令,相當於echo
9.接收引數
expect指令碼可以接受從bash命令列傳遞的引數,使用[lindex Sargy n]獲得。其中n從o開始,分別表示第一個,第二個;第三個.引數。
例:

set hostname [lindex $argv 0]   -------------------- 相當於hostname=$1
set password[ lindex $argv 1] ------------------------- 相當於password=$2

示例

免互動登入資料庫

#/usr/bin/expect
spawn mysql -uroot -p
expect {
"password" {send "abc123\r"; exp_continue}
}

相關文章