shell之免互動
目錄
- shell之免互動
- 一、Here Document 免互動
- 二、語法格式
- 三、實體
- 1、免互動方式實作對行數的統計,將要統計的內容置于標記”EOF“之間,直接將內容傳給wc -l來統計
- 2、通過read命令接收輸入并列印,輸入值是兩個EOF標記之間的部分,作為變數i的值
- 3、通過passwd給用戶設定密碼
- 4、支持變數替換
- 5、整體賦值給變數,然后通過echo 命令將變數值列印出來
- 6、關閉變數替換的功能,按照字符原本的樣子輸出,不做任何修改或替換
- 7、去掉每行之前的TAB字符或者空格
- 8、多行注釋
- 四、Expect
- 1、基本命令
- 五、實體
- su切換用戶
- 創建用戶并設定密碼
- 實作ssh自動登錄
- 免互動創建磁盤
一、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
向行程發送字串,用戶模擬用戶的輸入;該命令不能自動回車換行,一般要加\r(回車)或者\n
例:
方式一:
expect “密碼” {send “abc123\r”}————同一行send部分要有{}
方式二:
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或者*assword,如果匹配yes/no則輸出yes并再次執行判斷;如果匹配*assword則輸出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
(10)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
創建用戶并設定密碼
嵌入執行模式,將expect程序融入shell當中,方便執行和處理
> #! /bin/bash
> user=$1
> password=$2
> useradd $user ———— 非互動命令放在expect外面
> /usr/bin/expect <<-EOF ———————— 開始免交換執行 , expect開始標志
> spawn passwd $user —— 開啟-一個行程跟蹤passwd命令,expect只能捕捉該行程資訊
> expect "新的*"
> send "$ {password}\r"
> expect "重新*"
> send "$ {password} \r"
> expect eof
> EOF
實作ssh自動登錄
> #! /usr/bin/ expect
> set timeout 5
> set hostname [l index $argv 0 ]
> set password [l index $argv 1]
> spawn ssh $hostname
> expect {
> "Connection refused" exit ———— 連接失敗情況,比如對方ssh服務關閉
> "Name or service not known" exit —————— 找不到服務器,比如輸入的IP地址不正確
> " (yes/no)" {send "yes\r" ;exp_ continue}
> "password:" {send "$password\r"}
> interact
> exit ———————— interact后的命令不起作用
免互動創建磁盤
>#!/bin/bash
>/usr/bin/expect <<EOF
>spawn fdisk /dev/$1
>expect "命令(輸入 m 獲取幫助)" {send "n\n"}
>expect "Select (default p)" {send "p\n"}
>expect "磁區號" {send "\n"}
>expect "起始 扇區" {send "\n"}
>expect "Last 扇區, +扇區" {send "\n"}
>expect "命令(輸入 m 獲取幫助)" {send "w\n"}
>expect eof
>EOF
>fdisk -l
>mkfs.xfs -f /dev/$11 &>/dev/null
>if [ $? -ne 0 ];then
>echo "未格式化成功,請檢查腳本"
>else
>echo "格式化成功"
>fi
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/241951.html
標籤:其他
上一篇:Linux磁盤配額配置
