Как выполнить команды sudo с командами Expect & send в 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 (и, как следствие, ожидайте), фигурные скобки действуют как одиночные кавычки оболочки: запрещают расширение переменной.

Форма ожидания с несколькими шаблонами полезна для случая, когда вы можете не увидеть шаблон. exp_continueЗаявление по существу «петля» в пределах ожидать , так что вы можете отправить пароль и продолжить ожидать приглашения. Поскольку с шаблоном приглашения не связано никаких действий, управление переходит от ожидаемой команды к следующей.

Я бы порекомендовал вам сохранить это как отдельный скрипт. Первая строка должна быть

#!/usr/bin/expect -f

Если вы хотите встроить скрипт оболочки:

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

Обратите внимание на кавычки вокруг первого «END» - это приводит к одинарным кавычкам всего документа здесь, поэтому вам не нужно беспокоиться о том, что оболочка интерпретирует переменные Expect.


Привет Гленн, скрипт выполняется без ошибок, но я не могу увидеть вывод scirpt. Я делаю что-то неправильно в сценарии. Если да, пожалуйста, дайте мне знать, я сохраняю вывод в отдельном файле. вот скрипт, который я выполняю sasuke @ njob: ~ $ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ пароль хоста: sasuke @ hostname: ~ $ output = $ (список sudo virsh --all | awk '/ работает / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke

Вы не можете публиковать код в комментариях, пожалуйста, добавьте его в свой вопрос
Гленн Джекман

о, я прошу прощения за это. Спасибо, я сделал это. Пожалуйста, помогите мне.
Саске

Не знаю Добавьте exp_internal 1в начало сценария и прочитайте подробный вывод.
Гленн Джекман

3

Я хотел бы поделиться своим Scirpt. Я попробовал это в моей системе. это работает нормально.

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

Попробуйте завершить его командой «взаимодействовать», это должно работать.

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"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.