首頁 > 運維 > linux運維 > 主體

Linux Shell自動互動功能如何實現

PHPz
發布: 2023-05-29 12:43:18
轉載
2422 人瀏覽過

需求背景:

近日,在安裝某軟體流程,發現在安裝過程需要輸入一些資訊才能繼續下一步操作,在機器數量較少情況下,我們可以單一登入完成安裝操作,但當機器數量超過一定時,如果再手動登入操作,就會產生大量重複性操作,既不能帶來有效學習能力提升,同時也會極大產生不確定性,引發工作效率下降,那麼如何自動化完成某些操作呢,尤其是有互動功能的步驟呢,例如需要輸入帳號密碼?

1. EOF 多文本輸入

需求案例1

新交付了一批機器,每台機器只分配了一塊落盤,現在根據需求對該盤進行分割並實現掛載,如何實現?

需求分析:

對於一個盤,實作分割區掛載到不同目錄,通常思路有兩個:

方法一: 整塊磁碟作為一個PV ,整合成VG卷,再依分割不同LV卷大小分給不同目錄方法二: 透過fdisk 將磁碟直接分割成對應需求的大小,再對磁碟初始化,完成掛載

#方案解決

這裡我們為了示範互動功能,選擇方法二,實作腳本如下:

#!/bin/bash
fdisk /dev/sdb <<EOF
n
p
1
wq
EOF
 
 mkfs.xfs /dev/sdb1 &&  mkdir -p /data && mount /dev/sdb1 /data
echo &#39;/dev/sdb1 /data xfs defaults 0 2&#39; >> /etc/fstab
登入後複製

分析上述腳本,我們發現使用了一個關鍵字 EOF

  • EOF是END Of File的縮寫,表示自訂終止符.既然自訂,那麼EOF就不是固定的,可以隨意設定別名,在linux按ctrl-d就代表EOF .

  • EOF一般會配合cat能夠多行文字輸出.

##其用法如下:

<

.... //需要輸入的內容

EOF //結束

#例如使用

cat、<<、EOF>以互動方式編寫bash腳本,如下所示。

cat << EOF > script.sh
#!/bin/bash
 
printf "Hello\n"
printf "Wordl!\n"
EOF
登入後複製

Linux Shell自動互動功能如何實現

Linux Shell自動互動功能如何實現

合理地利用這三個,即可以完成對應多文本交互輸入,例如修改用戶密碼,正常情況下,需要連續輸入兩次密碼,兩次密碼一致才能修改成功,如下:

Linux Shell自動互動功能如何實現

上面我們學會了EOF 這個關鍵字,那麼我們試試透過它來修改密碼。腳本如下:

#!/bin/bash
 
cat << EOF| passwd 
新密码
新密码,与上述需一致
EOF
 
# or 不使用管道符
 
passwd << EOF
新密码
新密码,与上述需一致
EOF
登入後複製

實戰結果,成功修改密碼:

Linux Shell自動互動功能如何實現

#2. Expect 自動互動

#需求案例2

  新交付了一批機器,需要向每台機器分發文件,如何實現?

需求分析:

遠端拷貝檔案常用密令是scp 或rsync ,但是在傳送給每台機器時需要若輸入密碼,有的機器可能還需要輸入YES,輸入機器指紋訊息,如下:

Linux Shell自動互動功能如何實現

Expect 是在tcl基礎上的一個自動化互動套件, 在一些需要互動輸入指令的場景下, 可透過腳本設定自動進行互動通訊.其互動流程主要有以下5步驟:

0 定義變數

1 spawn啟動指定腳本或指令

2 expect比對結果關鍵字

3 send針對指定關鍵字發送指定指令

4 執行完成, 退出

但可惜的是os預設沒有安裝,因此需要先安裝才能使用

Expect is a tcl application for automating and testing interactive applications such as telnet, ftp, passwd, fsck, rlogin, tip, etc. Expect makes it easy for a script to control another program and interact with it

#方案解決:

1. 先檢查本機是否安裝了expect ,如果沒有安裝,需要手動安裝

# 检查是否安装了expect:
[root@localhost ~]# rpm -qi expect
Name        : expect
Version     : 5.45
Release     : 14.el7_1
Architecture: x86_64
Install Date: Fri 05 Aug 2022 07:26:04 AM CST
Group       : Development/Languages
....
 
# 如果没有安装, 使用yum安装expect ,通常会顺带把依赖包tcl 也安装了:
[root@localhost ~]# yum install -y expect  # -y  其实也是安装过程中一个交互,发现没,只是作为参数传入了
[root@localhost ~]# yum install -y tcl  # 如果上述命令提示已安装tcl了,此步可以忽略
 
# 查看expect的安装路径:
[root@localhost ~]#  which expect
/usr/bin/expect
登入後複製

2 .對應功能腳本開發,本案例腳本參考如下:

[root@test01 ~]# cat scp.exp
#! /usr/bin/expect
set file [lindex $argv 0]
set file2 [lindex $argv 1]
spawn scp -rp $file $file2 root@192.168.31.89:/tmp
expect {
 "(yes/no)" {send "yes\r";exp_continue}
 "*password:*" {send "Password\r"}
 
}
expect eof
exit -onexit {
 send_user "bye \n"
}
登入後複製

3. 分析上述腳本,有幾個點需要說明

#!/usr/bin/expect
登入後複製

腳本文件的第一行指明expect 安裝位置,具體可以參考2 中命令查看,指明腳本解析器,和Shell類似,表示程式使用Expect解析,這裡與一般bash 腳本不同,因此需要注意,通常我們會將expect腳本後綴修改成exp來和bash 腳本sh區別

set 設定變數值

set file [lindex $argv 0]

將傳入的第一個參數賦給file ,類似第二、三個參數

[lindex $argv 1] [lindex $argv 2] 等,後續呼叫時使用$file ,和shell 一樣。特殊參數:$argc

表示傳參的個數,

$argv0表示腳本的名稱spawn 表名要執行的腳本或程式命令,如ssh、scp等

格式: spawn [选项] [需要自动交互的命令或程序]

例如:spawn scp -rp $file $file2 root@192.168.31.89:/tmp #<==执行scp命令(注意开头必须要有spawn, 否则无法实现交互)

expect

需和spawn 配合使用 ,表示匹配spawn指定的脚本或命令的输出结果,如果与expect后面的字符串匹配,就执行下面的send命令,表示对结果响应反馈

有时命令的输出提示信息有可能会变化,所以可以在expect中使用模糊匹配,比如*

注意:匹配的动作也可以放在下一行,这样就不需要使用{}(大括号)了

send

在expect命令匹配指定的字符串后,发送指定的字符串给系统,这些命令可以支持一些特殊转义符号,例如:\r表示回车、\n表示换行、\t表示制表符等

exp_continue

从命令的拼写就可以看出命令的作用,即让Expect程序继续匹配的意思,如果需要一次匹配多个字符串,那么不同的匹配之间就要加上exp_continue,否则expect将不会自动输入指定的字符串。由于前面的都已经完成,最后一个不必加上exp_continue,它已经是最后一个了

exit

功能类似于Shell中的exit,即直接退出脚本,还可以利用这个命令对脚本做一些关闭前提示等工作

send_user

打印Expect脚本信息,类似Shell里的echo. 例如打印变量信息,验证数据传入是否正常

在掌握expect 基本使用方式后,我们写一个批量查看机器负载信息的小脚本,加强记忆

#! /usr/bin/expect
    set time 30
    set ip [lindex $argv 0]
 
    spawn ssh root@$ip uptime
    expect {
        "*yes/no" { send "yes\r"; exp_continue }
        "*password:" { send "$password\r" }
    }
    expect eof
登入後複製

实战结果:

Linux Shell自動互動功能如何實現

小试牛刀

在学习完以上两个方法,我们试着写一个脚本,结合上述两种方式,批量查看各机器目录挂载情况,并列举出来,参考脚本如下:

#!/bin/bash
 
ip="192.168.31.89"
username="root"
password="123456"
cmd=" df -PTh|grep ^/dev"
# 指定执行引擎
expect <<EOF
    set time 30
    spawn ssh $username@$ip  $cmd
    expect {
        "*yes/no" { send "yes\r"; exp_continue }
        "*password:" { send "$password\r" }
    }
    expect eof
EOF
登入後複製

以上是Linux Shell自動互動功能如何實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!