修正する

修正する

IPアドレスを提供するExpectスクリプトがあります。

#!/bin/expect -f
set nodename [lindex $argv 0]
spawn virsh console $nodename
expect "Escape character is"
send "\n"
expect "localhost login: " {
    send "root\n"
    expect "Password: "
    send "cloud123\n"
}
expect "~]#" {
        send "\n"
        send "ifconfig | grep 192.168.1. | awk \'{print \$2}\'"
        send "\n"
        expect '(\d+\.\d+\.\d+\.\d+)'
        send "logout"
}

スクリプトがこのIPアドレスを返すことを望みます。次のように、シェルスクリプトからこのExpectスクリプトを呼び出します。

#!/bin/bash
ip=$(expect GetIP.exp nodetwo)
echo $ip

Expectスクリプトが出力をシェルスクリプトに返すようにするにはどうすればよいですか?

答え1

いいですね。ロギングのオン/オフは機能しません。おそらくタイミングの問題でしょう。

次のように呼び出すと、次の期待スクリプトが機能します。

# ip=$(./virsh-expect nodetwo | tr -d '\r' | grep '^192.168')
# echo $ip 
192.168.122.99

trここで注意すべき重要な点は、grepを使用してシェルスクリプトでIPを見つけると、出力からキャリッジリターンが削除されることです。 Expectスクリプトはこれを「期待」しようとせず、次のルートシェルプロンプトを期待して終了します。

また、予想されるスクリプトをより一般的にしました。 "localhost login:" の代わりに "login:" だけを予想し (実際にホスト名を持つすべての VM で失敗し、ほとんど失敗する)、単純な "#" ルートシェルプロンプトの場合。

#!/usr/bin/expect -f
set nodename [lindex $argv 0]
spawn virsh console $nodename
expect "Escape character is"
send "\n\n"
expect "login: " {
    send "root\n"
    expect "Password: "
    send "cloud123\n"
}   
expect "# " {
        send "ifconfig | awk \'/192\.168/ {print \$2}\'"
        send "\n"
        expect "# "
        send "exit"
}

expect別のオプションはまったく使用せず、代わりにPerlExpect.pmまたはPythonを使用するpexpectことです。予想セッションとほぼ同じように機能しますexpectが、予想セッションからデータを抽出する方が簡単です。


expect私はまだ.NETを使用するよりも仮想マシンのIPアドレスを取得するより良い方法があると思いますvirsh console

virsh dumpxml以下は、MACアドレスを抽出し、次を使用して一致するdnsmasq-dhcpエントリを見つける方法です。/var/log/daemon.logawk

# mac=$(virsh dumpxml nodetwo | sed -n -e "/mac address/ s/.*'\([^']*\)'.*/\1/ p" | tail -1)
# ip=$(awk "/dnsmasq.*DHCPACK.*$mac/ {print \$7}" /var/log/daemon.log  | tail -1)
# echo $ip
192.168.122.99

私のシステムの仮想マシンには2つのネットワークインターフェイスがあり、最後のインターフェイスにのみ興味があるので、tail -1オンラインで使用しますvirsh dumpxmltail -1オンラインにアクセスするawkことは、私たちが得ることができるものだけを確認することです。最新MAC アドレスは dhcp によって割り当てられました。

(実際に私がシステムでテストしているVMは「nodetwo」ではなく「sid」と呼ばれていますが、あなたの質問に合わせて予想スクリプトの出力とパスワードを編集しました。また、私が使用しているIPアドレスも同じです。場合は192.168.1.xの代わりに192.168.122.xですが、これは細部でわずかな違いです。


修正する

私は私が作ったfreebsd仮想マシンのIPを見つけるために昨夜これを直接使う必要がありました。dhcpd代わりにISCを使用しているため、dnsmasqログ形式が少し異なります。このバージョンは次のようdnsmasqに動作しますdhcpd

$ cat find-vm-ip-by-name.sh
#!/bin/bash

mac=$(virsh dumpxml "$1" | sed -n -e "/mac address/ s/.*'\([^']*\)'.*/\1/ p" | tail -1)
ip=$(awk "/dnsmasq.*DHCPACK.*$mac/ {print \$7} ; /dhcpd.*DHCPACK.*$mac/ {print \$8}" /var/log/daemon.log  | tail -1)
echo $ip

答え2

次のことを試すことができます。

send_user $ip

「send_user」出力は標準出力に送信されます。スクリプトの実行中に画面にメッセージを送信するために使用されます。ユーザーフィードバック、バナー、エラーメッセージの生成に適しています。

関連情報