shell 腳本免交互 Here Document 和 expect

shell 腳本之免交互

 

 

一: Here Document 免交互

1.1 概述

  • 使用 I/O 重定向的方式將命令列表提供給交互式程序或命令。好比 ftp ,cat ,或者read 命令
  • 是標準輸入的一種替代品,能夠幫助腳本開發人員沒必要使用臨時文件來構建輸入信息,二十直接就地生產一個「文件」 並用做 「命令」 的標準輸入。 Here Document 也能夠與非交互式程序和命令一塊兒使用

1.2 語法格式

命令 << 標記linux

傳入的內容shell

標記bash

注意服務器

  • 標記可使用熱議合法字符(一般爲EOF)
  • 結尾的標記必定要頂格寫,前面不能有任何字符
  • 結尾的標記後面也不能有任何字符(包括空格)
  • 開頭標記先後的空格會被省略

1.3 示例

1.3.1 免交互方式實現對行數的統計,將要統計的內容放在標記之間

image-20210727202409965


1.3.2 經過read 命令接受輸入並打印

image-20210727202757071


1.3.3 經過passwd 給用戶設置密碼

image-20210727203105921


1.3.4 將內容輸入到文件中

image-20210728092114153


1.3.5支持變量替換

在寫入文件時,會先將變量替換爲實際值,在結合cat 命令完成寫入ssh

#!/bin/bash
file="EOF.txt"
i="school"

cat > $file <<EOF
this is my $i
EOF

cat EOF.txt

image-20210727204640444


1.3.6 總體賦值給變量,而後經過echo 命令將變量值打印

#!/bin/bash
var="great! i am going to school!"
myvar=$(cat <<EOF
        this is line 1.
        today is monday.
        $var
EOF
) #) 要另起一行寫,不能夠寫在EOF 後面


#變量要加上雙引號「」 ,不然內容將會輸出在1行中
echo "$myvar"

image-20210727205339452


1.3.7 關閉變量替換功能

#!/bin/bash
var="great! i am going to school!"
#在第一個標記兩邊加上單引號'' 便可關閉變量的替換功能
myvar=$(cat <<'EOF'
        this is line 1.
        today is monday.
        $var
EOF
) #")" 要另起一行寫,不能夠寫在EOF 後面

echo "$myvar"

image-20210727205624064


1.3.8 去掉每行以前的 TAB字符(沒法去掉空格形成的空)

#!/bin/bash
var="great! i am going to school!"

#在第一個標記前面加上"-" ,既能夠抑制各行行首的TAB
#注意,只是抑制TAB,而不是空格
myvar=$(cat <<-EOF
        this is line 1.
        today is monday.
        $var
EOF
) #) 要另起一行寫,不能夠寫在EOF 後面

echo "$myvar" 
~

image-20210727205946076


1.3.9 多行註釋

":"表明什麼都不作的空命令。中間標記區域的內容不會被執行,會被bash忽略掉,所以可達到批量註釋的效果ide

#!/bin/bash

# ":" 開頭的Here Document 標記內容不會被執行
: <<EOF
this is line 1.
today is monday.
EOF

echo "abcd"

image-20210727210427897


二:expect 工具

創建在tcl語言基礎上的一個工具,常被用於進行自動化控制和測試,解決shell腳本中交互相關的問題。工具

因此,須要先安裝軟件包 expecttcl測試

yum -y install expectthis


2.1 基本命令

2.1.1 腳本解釋器

expect 腳本中首先引入文件,代表使用的是哪個shellspa

#!/usr/bin/expect

img


2.1.2 spawn

spawn 後面一般跟一個linux 執行命令,表示會開啓一個會話,啓動進程,並跟蹤後續交互信息

spawn passwd root


2.1.3 expect

  • 判斷上次輸出結果中是否包含指定的字符串,若是有,則當即返回,不然就等待超時時間後返回。
  • 只能捕捉由spawn 啓動的進程的輸出
  • 用於接受命令執行後的輸出,而後和指望的字符串匹配

2.1.4 send

向進程發送字符串,用於模擬用戶的輸入;改命令不能自動回車換行,通常要加 \r (回車)或者 \n換行

  1. expect "密碼" {send "1234567\n"}      #同一行send 部分要有 { }
  2. expect "密碼"
    
    send  "1234567\n"          #換行send 部分不須要有 { }
  3. #expect 支持多分枝。只要匹配了其中一個狀況,執行相應的send 語句後,退出相應的expect語句
    expect 
    {
    	"密碼"  {send "1234567\n}
    	"password"  {send "1234567"}
    	}

2.1.5 結束符

  1. expect eof

    表示交互結束,等待執行結束,退回到原用戶,與spawn 對應

    如:切換到root 用戶,expect 腳本默認是等待10s,當執行完命令後,停留10s,而後自動切換回原用戶

  2. interact

    執行完成後保持交互狀態,吧控制權交給控制檯,會停留在目標終端而不會退回到原終端。這個時候就能夠手工操做。

    interact 後的命令不起做用。好比interact 後面添加exit ,並不會退出root用戶。

    而若是沒有interact ,則登陸完成後會退出,而不是留在遠程終端上

    使用interact會保持在終端而不會退回到原終端,好比切換到root用戶,會一直在root用戶狀態下; 好比ssh到另外一服務器,會一直在目標服務器終端,而不會切回的原服務器。

# expect eof 和 interact 只能二選一


2.1.6 set

expect 默認超時時間是10 秒,經過set 命令能夠設置會話超時時間。若不限制超時時間,則設置爲 -1

set timeout 10


2.1.7 exp_continue

  1. exp_continue 附加於某個 expect 判斷項以後,可使該項被匹配後,還能繼續匹配該 expect 判斷語句內的其餘項。exp_continue 相似於控制語句中的 continue 語句。表示容許 expect 繼續向下執行指令

  2. 使用exp_continue 時,若是跟蹤像passwd 這樣的輸入密碼後就結束的進程的命令,expect{} 外不要再加上expect eof 。由於spawn 進程結束後會默認向expect發送eof ,會致使後面的expect eof報錯

expect {
  "(yes/no)" {send "yes\n";exp_continue;}
	"*password"  {set timeout 300;send "1234567";}
	}
#判斷交互輸出中是否存在yes/no 或者*password 。若是匹配 yes/no 則輸出yes,並再次執行判斷;若是匹配*password 則輸出1234567,並結束該段expect6語句

2.1.8 send_user

send_user 表示回顯命令,至關於echo


2.2 接收參數

expect 腳本口語i接受從bash 命令行傳遞的參數,使用 [lindex $argv n] 得到。n 從0開始,分別表示第一個,第二個...... 參數

set hostname [lindex $argv 0]    
set password  [lindex $argv 1]

2.2.1免交互切換用戶

#!/usr/bin/expect

#設置超時時間爲5s
set timeout 5

#設置第一個位置參數
set username [lindex $argv 0]

#設置第二個位置參數
set password [lindex $argv 1]

#開啓跟蹤命令
spawn su - $username

#免交互執行,捕捉信息並匹配
expect "密碼:"
send "${password}\n"

#結束符
#若是設置成expect eof 則會切換用戶後,過5s,而後自動退回到原用戶
interact

image-20210727230630747


2.2.2 免交互遠程登陸

#!/usr/bin/expect

set timeout 5

set hostname [lindex $argv 0]
set password [lindex $argv 1]

spawn ssh $hostname

#設置多分支匹配
#ssh遠程,首次登陸須要保存登陸主機信息。
expect {
		"NO route to host" exit
		"Connection refused" exit
		"(yes/no)" {send "yes\n" ;exp_continue}
		"password:" {send "$password\n"}
}
interact

image-20210727232122952


2.3 嵌入執行模式

將expect 過程融入到 shell 當中,方便執行和處理

例:建立用戶並設置密碼

#!/bin/bash

#設置位置參數傳入
#設置第一個位置參數
username=$1
#設置第二個位置參數
password=$2

#注意,/usr/bin/expect解釋器不支持useradd
useradd $username


#使用Here Document 將expect 的輸入直接交給 /usr/bin/expect 執行
/usr/bin/expect <<EOF
#開啓命令跟蹤
spawn passwd $username

#免交互執行,捕捉信息並匹配
expect "新的 密碼"
send "${password}\n"

expect "從新輸入新的 密碼"
send "${password}\n"

#結束免交互
expect eof
EOF
#結尾標記

image-20210727232824224

相關文章
相關標籤/搜索