文章目錄
- 一、Here Document免互動
- (一)、Here Document概述
- (二)、Here Document使用注意事項
- (三)、Here Document免互動示例
- 1、通過read命令接收輸入并列印
- 2、通過passwd給用戶設定密碼
- (四)、Here Document變數設定
- 1、變數替換
- 2、變數設定
- (五)、Here Document格式控制
- 1、關閉變數替換功能,按照字符原本的樣子輸出,不做任何修改或替換
- 2、去掉每行之前的TAB字符
- (六)、Here Document多行注釋
- 1、語法格式
- 2、舉例:
- 總結
- 二、Expect免互動
- (一)、Expect概述
- (二)、Expect基本命令
- 1、Expect安裝
- 2、基本命令
- (1)腳本解釋器
- (2) spawn
- (3) expect
- (4) send
- (5)結束符
- (6) set
- (7) exp_continue
- (8) send_user
- (9) 接收引數
- (三)、Expect直接執行
- (四)、Expect嵌入執行
- 總結:Expect腳本命令總結
一、Here Document免互動
(以標簽的形式實作免互動,標簽里面的字符可以自行定義)
(一)、Here Document概述
- 使用I/O重定向方式將命令串列提供給互動式程式
- 標準輸入的一種替代品
- 語法格式
命令 <<標記(EOF)
… (標記之間是傳入的內容)
…
標記(EOF)
(二)、Here Document使用注意事項
- 標記可以使用任意合法字符(大寫字母)(EOF、FOE,前后要一致)
- 結尾的標記一定要頂格寫,前面不能有任何字符
- 結尾的標記后面也不能有任何字符(包括空格)
- 開頭標記前后的空格會被省略掉
(三)、Here Document免互動示例
1、通過read命令接收輸入并列印
[root@localhost ~]# read i <<EOF
> hello world
> my name is gcc
> EOF
[root@localhost ~]# echo $i
hello world
#######直接賦值,只能賦值一行
[root@localhost ~]# vim a.sh
#!/bin/bash
read i <<EOF
hello world
my name is gcc
EOF
echo $i
[root@localhost ~]# sh a.sh
hello world
2、通過passwd給用戶設定密碼
[root@localhost opt]# vim a.sh
#!/bin/bash
passwd lisi <<EOF
abc123 #這兩行是輸入的密碼和確認的密碼
abc123
EOF
[root@localhost opt]# sh a.sh
更改用戶 lisi 的密碼 ,
新的 密碼:無效的密碼: 密碼少于 7 個字符
重新輸入新的 密碼:passwd:所有的身份驗證令牌已經成功更新,
(四)、Here Document變數設定
1、變數替換
在寫入檔案時會先將變數替換成實際值,再結合 cat 命令完成寫入
[root@gcc zhengze1]#vim test.txt
my name is gcc
--------------------------------------------------
[root@gcc zhengze1]#vim test.sh
#!/bin/bash
filename="test.txt"
name="123"
cat > $filename <<EOF
the number is $name
EOF
---------------------------------------------------
[root@gcc zhengze1]#sh test.sh
[root@gcc zhengze1]#cat test.txt
the number is 123
2、變數設定
整體賦值給變數,然后通過 echo 命令將變數列印出來
[root@client opt]# num1=111
[root@client opt]# echo $num1
111
[root@client opt]# num2=$(cat <<EOF
> 222
> $num1
> EOF
> )
[root@client opt]# echo $num2
222 111
(五)、Here Document格式控制
1、關閉變數替換功能,按照字符原本的樣子輸出,不做任何修改或替換
單引號關閉變數替換,就把EOF當做字串
[root@localhost opt]# num1=111
[root@localhost opt]# echo $num1
111
[root@localhost opt]# cat <<'EOF' #對標記加單引號,即可關閉變數替換
> 222
> $num1
> EOF
222
$num1
2、去掉每行之前的TAB字符
表示抑制行首的TAB作用
[root@gcc zhengze1]#vim d.sh
#!/bin/bash
var="Great! I am going to school!"
myvar=$(cat <<-'EOF'
this is line 1.
today is monday.
$var
EOF
)
echo $myvar
--------------------------------------
[root@gcc zhengze1]#sh d.sh #將TAB字符給去掉了
this is line 1. today is monday. $var
(六)、Here Document多行注釋
Bash的默認注釋是“#”,該注釋方法只支持單行注釋:Here Document 的引入解決了多行注釋的問題,
“:”代表什么都不做的空命令,中間標記區域的內容不會被執行,會被bash 忽略掉,因此可達到批量注釋的效果,
通過Here Document方式使Bash支持多行注釋
1、語法格式
:<<DO-NOTHING '前面命令變為冒號'
注釋1
注釋2
......
DO-NOTHING
2、舉例:
[root@gcc zhengze1]#vim d.sh
#!/bin/bash #這是沒有被注釋的內容,可以正常顯示
var="Great! I am going to school!"
myvar=$(cat <<-'EOF'
this is line 1.
today is monday.
$var
EOF
)
echo $myvar
: <<FOE #這是被注釋的內容,不能顯示
echo "hello"
echo "world"
FOE
------------------------------------------------------------------------
[root@gcc zhengze1]#sh d.sh #執行后的結果只顯示沒有被注釋的內容
this is line 1. today is monday. $var
總結
注意事項
(1)標記可以使用任意的合法字符,不僅僅是EOF,但約定俗成的是EOF,必須大寫
(2)結尾標記一定要頂格寫,前面不能有任何字符,后面也不能有任何字符,這個不容易發現
(3)開頭標記前后的空格會被省略掉
二、Expect免互動
(一)、Expect概述
-
Expect是建立在tcl 語言基礎上的一個工具,常被用于自動化控制和測驗,主要解決shell腳本中不可互動的問題,對于大規模的linux運維很有幫助
-
在Linux運維和開發中,我們經常需要遠程登錄服務器進行操作,在登錄的程序是一個互動的程序,可能會需要輸入yes/no password等資訊,
-
為了模擬這種輸入,可以使用Expect腳本
(二)、Expect基本命令
1、Expect安裝
系統一般不自帶,需要自己安裝
安裝命令
yum -y install expect
2、基本命令
(1)腳本解釋器
- expect 腳本中首先引入檔案,表明使用的是哪一個shell,
#!/usr/bin/expect
(2) spawn
- spawn 后面通常跟一個Linux執行命令,表示開啟一個會話、啟動行程,并跟蹤后續互動資訊,
例: spawn passwd gcc #跟蹤啟動更改gcc用戶密碼的行程
(3) expect
- 判斷上次輸出結果中是否包含指定的字串,如果有則立即回傳,否則就等待超時時間后回傳;只能捕捉由spawn啟動的行程的輸出;
- 用于接收命令執行后的輸出,然后和期望的字串匹配
(4) send
- 向行程發送字串,用于模擬用戶的輸入:該命令不能自動回車換行,一般要加 \r (回車)或者 \n
- 例:
方式一:
expect "密碼" (send "abc123\r") #同一行send部分要有 (),該行意思是當出現“密碼”字符時,就將abc123輸入進去
方式二:
expect "密碼"
send "$abc123\r" #換行send部分不需要有()
方式三:
expect 支持多個分支
expect
{ #只要匹配了其中一個情況,執行相應的send陳述句后退出該expect陳述句
"密碼1" {send "abc123\r"}
"密碼2" {send "123456\r"}
"密碼3" {send "123123\r"}
}
(5)結束符
expect eof
-
表示互動結束,等待執行結束,退回到原用戶,與spawn對應,
-
比如切換到root用戶, expect腳本默認的是等待10s,當執行完命令后,默認停留10s后,自動切回了原用戶
-
interact
執行完成后保持互動狀態,把控制權交給控制臺,會停留在目標終端而不會退回到原終端,這個時候就可以手工操作了,interact后的命令不起作用,比如interact后添加exit,并不會退出root用戶,而如果沒有interact則登錄完成后會退出,而不是留在遠程終端上,
使用interact會保持在終端而不會退回到原終端,比如切換到root用戶,會一直在root用戶狀態下:比如ssh到另一服務器,會一直在目本服務器終端,而不會切回的原服務器,
注意:expect eof與interact只能二選一,
(6) set
- expect 默認的超時時間是10秒,通過set命令可以設定會話超時時間,若不限制超時時間則應設定為-1
例:set timeout 30
(7) exp_continue
- exp_continue 附加于某個 expect 判斷項之后,可以使該項被匹配后,還能繼續匹配該expect判斷陳述句內的其他項,exp_continue類似于控制陳述句中的continue陳述句,表示允許expect繼續向下執行指令,
- 例如:下例將判斷互動輸出中是否存在 yes/no 或 *password ,如果匹配 yes/no 則輸出 yes 并再次執行判斷;如果匹配 *password ,則輸出 abc123 并結束該段 expect 陳述句,
expect {
"(yes/no)" {send "yes\r"; exp_continue;}
"*password" {set timeout 300; send "abc123\r";}
}
注意:使用exp_continue時,如果跟蹤像 passwd 這樣的輸入密碼后就結束行程的命令,expect{} 外不要再加上 expect eof ,因為 spawn 行程結束后會默認向 expect 發送 eof ,會導致后面的 expect eof 執行報錯,
(8) send_user
- send_user 表示回顯命令,相當于echo
(9) 接收引數
- expect腳本可以接受從bash命令列傳遞的引數,使用 [lindex $argv n] 獲得,其中n從0開始,分別表示第一個,第二個,第三個…引數,
- 例:
set hostname [lindex $argv 0] #相當于hostname=$1
set password [lindex $argv 1] # 相當于password=$2
(三)、Expect直接執行
- 需要使用 expect 命令去執行腳本
su切換用戶
#!/usr/bin/expect
#設定超時時間
set timeout 5
#引數傳入
set username [lindex $argv 0]
set password [lindex $argv 1]
#開始追蹤命令
spawn su $username
#免互動執行,捕捉資訊并匹配
expect "密碼"
send "$password\r"
expect "*]#"
send_user "ok"
#把控制權交給控制臺
interact
或者
expect eof
示例:(以SSH為例)
其中,$argv 0 代表位置變數$1
$argv 1 代表位置變數$2
#!/usr/bin/expect 是Expect二進制檔案的路徑
[root@localhost~]#vim a.sh
#!/usr/bin/expect
set timeout 60 設定超時時間
log file test.log
log_user 1
set hostname [lindex $argv 0] '變數定義'
set password [lindex $argc 1]
spawn ssh root @$hostname '啟動spawn'
expect { '匹配條件'
"(yes/no)"
{send "yes\r";exp_continue}
"*password"
{send "$password\r"}
}
interact '將權限轉交控制臺'
(四)、Expect嵌入執行
將 expect 程序融入 Shell 當中,方便執行和處理
創建用戶并設定密碼
#!/bin/bash
user=$1
password=$2
#非互動命令放在expect外面
useradd $user
#開始免交換執行
/usr/bin/expect <<-EOF #expect開始標志
spawn passwd $user #開啟一個行程跟蹤 passwd 命令, expect 只能捕捉該行程資訊
expect "新的*"
send "${password}\r"
expect "重新*"
send "${password}\r"
expect eot
EOF
示例:(以SSH為例)
[root@localhost~]#vim b.sh
#!/bin/bash
hostname=$1
password=$2
/usr/bin/expect<<-EOF
spawn ssh root@${hostname}
expect {
"(yes/no)"
{send "yes\r";exp_continue}
"*password"
{send "$password\r"}
}
expect "*]#"
send "exit\r"
expect eof
EOF 'Expect結束標志,EOF前后不能有空格'
總結:Expect腳本命令總結
#!/usr/bin/expect -re
告訴作業系統腳本里的代碼使用那一個shell來執
-re 表示啟用正則表達匹配
2. set timeout -1
設定超時時長 -1 代表永不過期,默認時10秒
3. exp_continue
表示回圈匹配,匹配到改關鍵字后繼續從頭開始匹配,若不加exp_continue則會直接退出
4. expect eof
匹配結尾 例如執行命令結束時則可以匹配到 eof
5. exit、interact
exit互動結束退出
interact表示執行完后保持互動狀態,把控制權交給控制臺,這個時候就可以手工操作了
6. exp_send/send
都是向程式發送字串,可以理解為輸入
7. send_user
send_user 命令用來把后面的引數輸出到標準輸出中去,默人的send、exp_send 命令都是將引數輸出到程式中去的,
8.如何使用
mac 上直接使用 ./XX.sh 執行上述腳本不行,需要使用 expect XX.sh 才能正確執行
9.除錯
expect -d XX.sh輸出每次執行的程序可以用于撰寫腳本時除錯之用
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241452.html
標籤:其他
下一篇:ceph集群搭建
