Як виконати команди 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


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

Ви не можете розміщувати код у коментарях, додайте його у своєму питанні
glenn jackman

о, мені шкода за це. Дякую, що я це зробив. Будь ласка, допоможіть мені.
Саске

Не знаю. Додайте exp_internal 1до вершини сценарію та прочитайте багатослівний вихід.
glenn jackman

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

Спробуйте закінчити це командою "взаємодія", яка повинна працювати.

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.