Expect&sendコマンドでsudoコマンドをbashスクリプトで実行するにはどうすればよいですか?


10

誰かがsudoコマンドを実行する方法を教えてもらえますexpectか?以下を試しましたが、うまくいきません。誰か私に提案をお願いできますか?

set login "sasuke"
set addr "hostname"
set pw "mypasswd"
spawn ssh $login@$addr
expect "$login@$addr\'s password:"
send "$pw\r"
expect "#"
send "output=$(sudo virsh list --all | awk "/running/{print \$2}" | tail -2); sudo virsh dominfo $output"
expect "password:"
send "$pw\r"
expect "#"

以下のスクリプトを試したところ、エラーなしで実行されましたが、出力が得られませんでした。スクリプトと実行時の出力を次に示します。ここのどこで間違いをしていますか?

set login "sasuke"
set addr "hostname"
set pw "mypasswd"
spawn ssh $login@$addr
expect "$login@$addr's password:"
send "$pw\r"
expect "#"
send {output=$(sudo virsh list --all | awk '/running/{print $2}' | tail -2)}
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}
send {sudo virsh dominfo "$output"}    ;# don't know if you need quotes there
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}

実行

sasuke@njob:~$ ./hypr.sh 
spawn ssh sasuke@hostname 
sasuke@hostname's password: 
sasuke@hostname:~$ output=$(sudo virsh list --all | awk '/running/{print $2}' | tail -10)sudo virsh dominfo '$output' sasuke@njob:~$

回答:


10
set login "sasuke"
set addr "hostname"
set pw "mypasswd"
spawn ssh $login@$addr
expect "$login@$addr's password:"
send "$pw\r"
expect "#"
send {output=$(sudo virsh list --all | awk '/running/{print $2}' | tail -2)}
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}
send {sudo virsh dominfo "$output"}    ;# don't know if you need quotes there
expect {
    password: {send "$pw\r"; exp_continue}
    "#"
}

Tclでは(そして拡張すると、expect)、波括弧はシェルの単一引用符のように機能します。つまり、変数の展開を抑制します。

マルチパターン形式のexpectは、パターンが表示されない場合に役立ちます。exp_continueあなたがパスワードを送信し、プロンプトを期待し続けることができるように文は基本的に内の「ループ」を期待しています。プロンプトパターンに関連付けられているアクションがないため、expectコマンドから次のコマンドに制御が渡されます。

これを別のスクリプトとして保存することをお勧めします。最初の行は

#!/usr/bin/expect -f

シェルスクリプトに埋め込む場合:

#!/bin/sh
expect <<'END'
   # code as above
END

最初の「END」の前後の引用符に注意してください。これは、ヒアドキュメント全体を単一引用符で囲む効果があるため、シェルがExpect変数を解釈することを心配する必要はありません。


こんにちはGlenn、スクリプトはエラーなしで実行されていますが、スクリプトの出力を表示できません。スクリプトで何か間違ったことをしていますか?はいの場合は、出力を別のファイルに保存することを教えてください。ここに私が実行しているスクリプトがありますsasuke @ njob:〜$ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ hostname's password:sasuke @ hostname:〜$ output = $(sudo virsh list --all | awk '/ランニング/ {$ 2印刷}」|尾-10)のsudo virshをdominfo '$出力'サスケ@ njob:〜$
サスケ

コメントにコードを投稿することはできません。質問に追加してください
glenn jackman 2013年

ああ、ごめんなさい。ありがとう。私を助けてください。
sasuke

分からない。exp_internal 1スクリプトの先頭に追加して、詳細な出力を確認します。
グレン・ジャックマン2013年

3

私のスクリプトを共有したいと思います。私のシステムでこれを試しました。これは正常に動作しています。

#!/usr/bin/expect
set username "myname"
set password "mypasswd"
set hosts "hostname"
foreach line [split $ip \n] {
spawn ssh -o StrictHostKeyChecking=no $username@$hosts
expect "$username@$hosts's password:"
send -- "$password\n"
expect "$"
send -- "sudo virsh list|awk '{print \$2}'|grep 'inmobi' >vm.list; for host in `cat vm.list`; do sudo virsh dominfo \$host >> vm.info; done\n"
expect "$"
send -- "$password\n"
expect "$"
send -- "exit\n"

1

機能するはずの「interact」コマンドで終了してください。

spawn ssh -l $username $ip -p $sshport
sleep 5
expect "password:"
send "$pass\r"
interact

0

引用符内で引用符をバックスラッシュする必要があるかもしれません。それ以外の場合expectは、「awk」の後にコマンドが終了したと見なします。

send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.