1. 程式人生 > 其它 >shell指令碼 免互動

shell指令碼 免互動

一、Here Document 免互動

使用I/O重定向的方式將命令列表提供給互動式程式或命令,比如ftp、cat或read命令
是標準輸入的一種替代品可以幫助指令碼開發人員不必使用臨時檔案來構建輸入資訊,而是直接就地產生出一個“檔案”並用作“命令”的標準輸入。Here Document 也可以與非互動式程式和命令一起使用

二、語法格式

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

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

三、例項

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

> wc -l <EOF
> Line 1
> Line2
> EOF

2、通過read命令接收輸入並列印,輸入值是兩個EOF標記之間的部分,作為變數i的值

> read i <<EOF
> Hi
> EOF
> echo $i

3、通過passwd給使用者設定密碼

> passwd lisi <<EOF
> abc1234——————這兩行是輸入的密碼和確認密碼
> abc1234
> EOF

4、支援變數替換

在寫入檔案時會先將變數替換成實際值,再結合cat命令完成寫入
> #!/bin/bash
> file="EOF1.txt"
> i="school"
> cat > $file <<EOF
> I am going to $i
> EOF
> cat EOF1.txt

5、整體賦值給變數,然後通過echo 命令將變數值打印出來

> #!/bin/bash
> var="Great! I am going to school!"
> myvar=$(cat <<EOF
> This is Line 1.
> Today is Monday.
> $var
> EOF
> )
> echo $myvar

在這裡插入圖片描述
在這裡插入圖片描述
6、關閉變數替換的功能,按照字元原本的樣子輸出,不做任何修改或替換

>#!/bin/bash
>var="Great! I am going to school!"
>myvar=$(cat <<'EOF'——————對標記加單引號,即可關閉變數替換
>This is Line 1.
>Today is Monday.
>$var
>EOF
>)
>echo $myvar

在這裡插入圖片描述
在這裡插入圖片描述
7、去掉每行之前的TAB字元或者空格

> #!/bin/bash
> var="Great! I am going to school!"
> myvar=$(cat <<-'EOF'——————在標記前加”-“,即可抑制個行首TAB或空格
> ​							This is Line 1.
> ​					Today is Monday.
> ​			$var
> EOF
> )
> echo -e "$myvar"

在這裡插入圖片描述
在這裡插入圖片描述
8、多行註釋

Bash的預設註釋是”#“,該註釋方法只支援單行註釋,Here Document的引入解決了多行註釋的問題
":"代表上面都不做的空命令,中間標記區域的內容不會倍執行,會被bash忽略掉,因此可達到批量註釋的效果
> #!/bin/bash
> var="Great! I am going to school!"
> : <<-‘EOF’——————多行註釋,“:”開頭的 Here Document 標記內容不會被執行
> ​							This is Line 1.
> ​					Today is Monday.
> ​			$var
> EOF
> echo myvar

在這裡插入圖片描述

四、Expect

建立在tcl語言基礎上的一個工具,常被用於進行自動化控制和測試,解決shell指令碼中互動相關的問題
rpm -1 expect
rpm -q tcl
yum -y install expect
1、基本命令
(1)指令碼直譯器
expect指令碼種首先引入檔案,表明使用的是哪一個shell#!/usr/bin/expect
(2)spawn
spawn後面通常跟一個Linux執行命令,表示開啟一個會話、啟動程序,並跟蹤後續互動資訊。例:spawn passwd root
(3)expect
判斷上次輸出結果中是否包含指定的字串,如果有則立即返回,否則就等待超時時間後返回
只能捕捉由spawn啟動的程序的輸出
用於接收命令執行後的輸出,然後和期望的字串匹配
(4)send
向程序傳送字串,用6
(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
(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
(10)expect直接執行
需要使用expect命令執行指令碼(7)exp_continue
exp_continue附加於某個expect判斷項之後,可以使該項被匹配後,還能繼續匹配該expect判斷語句內的其他項,exp_continue類似於控制語句中的continue語句,表示允許expect繼續向下執行指令戶模擬使用者的輸入;該命令不能自動回車換行,一般要加\r(回車)或者\n
注意:使用exp_continue時,如果跟蹤像passwd這樣的輸入密碼後就結束程序的命令,expect{}外不要再加上expect eof,因為spawn程序結束後會預設向expect傳送eof,會導致後面的expect eof執行報錯