如何在bash脚本中使用Expect&send命令执行sudo命令?

任何人都可以告诉我如何执行sudo命令吗? 我尝试了以下但这不起作用。 有人可以给我一些建议吗?

 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:~$ 

 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中(并且,通过扩展,期望),花括号的行为类似于shell的单引号:禁止变量扩展。

期望的多模式forms对于您可能看不到模式的情况很有用。 exp_continue语句基本上在期望内“循环”,因此您可以发送密码并继续期望提示。 由于没有与提示模式相关联的操作,因此控制从expect命令传递到下一个命令。

我建议您将其另存为单独的脚本。 第一行应该是

 #!/usr/bin/expect -f 

如果要嵌入shell脚本:

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

请注意第一个“END”周围的引号 - 它具有单引用整个here文档的效果,因此您不必担心shell会解释Expect变量

我想分享我的看法。 我在我的系统上试过这个。 这工作正常。

 #!/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" 

我想你可能需要反驳引号内的引号。 否则expect认为命令在“awk”之后结束:

 send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output" 

尝试使用它应该工作的“交互”命令来结束它。

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