Làm cách nào để thực thi các lệnh sudo với Expect & send các lệnh trong bash script?


10

Bất cứ ai có thể cho tôi biết làm thế nào để thực hiện sudocác lệnh với expect? Tôi đã thử sau đây nhưng điều này không hiệu quả. Bất cứ ai có thể cho tôi đề nghị xin vui lòng?

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

Khi tôi thử đoạn script dưới đây, nó thực thi không có lỗi, nhưng tôi không nhận được kết quả đầu ra. Đây là kịch bản và đầu ra khi nó thực thi. Tôi đang mắc lỗi ở đâu?

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}
    "#"
}

Chấp hành

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

Câu trả lời:


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}
    "#"
}

Trong Tcl (và, bằng cách mở rộng, mong đợi), dấu ngoặc nhọn hoạt động giống như dấu ngoặc đơn của shell: ức chế mở rộng biến.

Dạng kỳ vọng đa mẫu rất hữu ích cho trường hợp bạn có thể không nhìn thấy mẫu. Câu exp_continuelệnh về cơ bản là "các vòng lặp" trong phạm vi mong đợi để bạn có thể gửi mật khẩu và tiếp tục mong đợi lời nhắc. Vì không có hành động liên quan đến mẫu dấu nhắc, điều khiển chuyển từ lệnh mong đợi sang lệnh tiếp theo.

Tôi khuyên bạn nên lưu nó dưới dạng một tập lệnh riêng biệt. Dòng đầu tiên phải là

#!/usr/bin/expect -f

Nếu bạn muốn nhúng vào một tập lệnh shell:

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

Lưu ý các trích dẫn xung quanh "KẾT THÚC" đầu tiên - có tác dụng trích dẫn toàn bộ tài liệu ở đây để bạn không phải lo lắng về trình bao diễn giải các biến Mong đợi


Xin chào Glenn, tập lệnh đang thực thi không có lỗi, nhưng tôi không thể thấy đầu ra của scirpt. Tôi đang làm bất cứ điều gì sai trong kịch bản. Nếu có, xin vui lòng cho tôi biết tôi lưu đầu ra trong tập tin riêng biệt. đây là đoạn script tôi đang thực thi sasuke @ njob: ~ $ ./hypr.sh spawn ssh sasuke @ hostname sasuke @ hostname 'password: sasuke @ hostname: ~ $ output = $ (danh sách sudo virsh --all | awk' / đang chạy / {print $ 2} '| tail -10) sudo virsh dominfo' $ output 'sasuke @ njob: ~ $
sasuke

Bạn không thể đăng mã trong các bình luận, vui lòng thêm nó vào câu hỏi của bạn
glenn jackman

oh tôi xin lỗi vì điều đó Cảm ơn tôi đã làm nó. Hãy giúp tôi ra.
sasuke

Đừng biết nữa. Thêm exp_internal 1vào đầu tập lệnh và đọc đầu ra dài dòng.
glenn jackman

3

Tôi muốn chia sẻ scirpt của tôi. Tôi đã thử điều này trên hệ thống của tôi. cái này hoạt động tốt

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

Cố gắng kết thúc nó bằng lệnh "tương tác" mà nó sẽ hoạt động.

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

0

Tôi nghĩ rằng bạn có thể cần phải gạch chéo lại các trích dẫn trong dấu ngoặc kép. Mặt khác expectnghĩ rằng lệnh kết thúc sau "awk":

send "output=$(sudo virsh list --all | awk \"/running/{print \$2}\" | tail -2); sudo virsh dominfo $output"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.