ホームページ >運用・保守 >Linuxの運用と保守 >Linux Shell自動対話機能の実装方法

Linux Shell自動対話機能の実装方法

PHPz
PHPz転載
2023-05-29 12:43:182469ブラウズ

需要の背景:

最近、あるソフトウェアのインストール中に、次のステップに進むためにいくつかの情報を入力する必要があることがわかりました。マシンの数が少ない場合、 1 台のマシンではログインしてインストールを完了できますが、マシンの数が一定レベルを超えると、手動ログイン操作では大量の反復操作が発生し、効果的な学習能力は向上しないだけでなく、大幅なコストが発生します。では、特定の操作、特にアカウントとパスワードの入力の必要性などの対話型機能を伴う手順を自動化する場合はどうでしょうか?

1. EOF マルチテキスト入力

要件ケース 1

マシンの新しいバッチが配信されました。各マシンには 1 つのディスクのみが割り当てられます。現在、ディスクが割り当てられています。要求に応じてパーティションを分割してマウントするにはどうすればよいですか?

要件分析:

ディスクの場合、パーティションを別のディレクトリにマウントするには、通常 2 つのアイデアがあります:

方法 1: ディスク全体を PV として使用し、統合する方法 2: fdisk を使用してディスクを対応するサイズに直接分割し、ディスクを初期化してマウントを完了します。

解決策

ここでは、対話型機能をデモンストレーションするために方法 2 を選択します。実装スクリプトは次のとおりです:

#!/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 と連携して複数行を出力します。 text.

  • その使用法は次のとおりです:

.... //必要なもの

#EOF //End

たとえば、

cat、、

> を使用します。以下に示すように、bash スクリプトを対話的に作成します。

cat << EOF > script.sh
#!/bin/bash
 
printf "Hello\n"
printf "Wordl!\n"
EOF

Linux Shell自動対話機能の実装方法

これら 3 つを適切に使用すると、ユーザー パスワードの変更など、対応するマルチテキストの対話型入力を完了できます。パスワードを 2 回続けて入力する必要があります。次のように 2 つのパスワードが一致する場合にのみ、変更が成功します: Linux Shell自動対話機能の実装方法

上でキーワード EOF を学習しました。それを使ってパスワードを変更してみましょう。スクリプトは次のとおりです: Linux Shell自動対話機能の実装方法

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

実際の結果、パスワードは正常に変更されました:

2. 自動対話が期待されますLinux Shell自動対話機能の実装方法

要件ケース 2

  新しく配信されたマシンのバッチを各マシンに分散する必要があります。これを実現するにはどうすればよいですか?

要件分析:

ファイルのリモート コピーに一般的に使用されるパスワードは scp または rsync ですが、各マシンに転送するときにパスワードを入力する必要があります。一部のマシンでは「YES」と入力する必要がある場合もあります。

Expect は、tcl に基づいた自動対話型スイートです。命令の対話型入力が必要な一部のシナリオでは、対話型通信が可能です。対話プロセスには主に次の 5 つのステップがあります: Linux Shell自動対話機能の実装方法

0 変数を定義する

1 指定されたスクリプトまたはコマンドを開始するために生成する

2 期待する結果のキーワードと一致します

3 send指定されたキーワードに対して指定されたコマンドを送信します

4 実行が完了しました、終了します

ただし、残念ながら、デフォルトでは OS がインストールされていないため、

#Expect は、Telnet、ftp、passwd、fsck、rlogin、tip などの対話型アプリケーションを自動化およびテストするための tcl アプリケーションです。Expect を使用すると、スクリプトで別のスクリプトを簡単に制御できます。

解決策:

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. 上記のスクリプトを分析すると、説明する必要がある点がいくつかあります。 ##スクリプト ファイルの最初の行は、予期されるインストール場所を示します。詳細については、2 のスクリプト パーサーとシェルを指定するコマンドを参照してください。同様に、プログラムが一般的な解析とは異なる、Expect 解析を使用することを意味します。 bash スクリプトなので、通常は、bash スクリプトと区別するために、expect スクリプトのサフィックスを exp に変更することに注意する必要があります。 sh

set 変数値の設定

set file [ lindex $argv 0]

2 番目と 3 番目のパラメータと同様に、ファイルに渡される最初のパラメータを割り当てます。

[lindex $argv 1] [lindex $argv 2]

など。

$file を使用します。後続の呼び出しの

はシェルと同じです。特別なパラメータ: $argc は渡されるパラメータの数を表します、$argv0 はスクリプトの名前を表します

スポーン テーブル名はスクリプトです実行されるプログラム コマンド (ssh、scp など)。<p>格式: spawn [选项] [需要自动交互的命令或程序]</p> <p>例如:<code>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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。