期望脚本ssh返回无效的命令名称

Sub*_*jee 6 expect

我正在尝试编写一个期望脚本,它将ssh到服务器,发送sudo su,然后检查iptables状态并将输出放在服务器上的日志文件中.下面是脚本.

1 #!/usr/bin/expect
  2 exp_internal 1
  3 log_user 0
  4 set timeout 10
  5 set password  "******"
  6 
  7 spawn /usr/bin/ssh -l subhasish *.*.*.* -p 10022
  8 
  9 expect {
 10      -re "password: " {send "$password\r"}
 11      -re "$ "  {send "sudo su\r"}
 12      -re "[sudo] password for subhasish:" {send "$password\r"}
 13      -re "# "  {send "service iptables status\r"}
 14        }
 15 set output $expect_out(buffer)
 16 send "exit\r"
 17 puts "$output\r\n" >> output.log
Run Code Online (Sandbox Code Playgroud)

但是在调试模式下运行时,我会收到这样的错误;

expect -d testcase
expect version 5.44.1.15
argv[0] = expect  argv[1] = -d  argv[2] = testcase  
set argc 0
set argv0 "testcase"
set argv ""
executing commands from command file testcase
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {24105}
invalid command name "sudo"
    while executing
"sudo"
    invoked from within
"expect {
     -re "password: " {send "$password\r"}
     -re "$ "  {send "sudo su\r"}
     -re "[sudo] password for subhasish:" {send "$password\r"}
 ..."
    (file "testcase" line 9)
Run Code Online (Sandbox Code Playgroud)

不知道我哪里错了.它说无效的命令名称"sudo",我想这是因为期望不了解这些命令.如何绕过它.请帮忙.谢谢.

gle*_*man 13

问题出在这一行

-re "[sudo] password for subhasish:" {send "$password\r"}
Run Code Online (Sandbox Code Playgroud)

在Tcl中(因此在期望中)方括号是命令替换的语法(如shell中的反引号).因此,您需要转义括号或使用不同的引号来阻止各种扩展:

-re {[sudo] password for subhasish:} {send "$password\r"}
Run Code Online (Sandbox Code Playgroud)

这带来了一个不同的问题:你期望看到这些确切的字符吗?因为您指示期望将其视为正则表达式,并且正则表达式中的方括号表示字符类,因此它将匹配单个字符,"s","u","d"或"o" ".所以你可能需要的是:

-re {\[sudo\] password for subhasish:} {send "$password\r"}
Run Code Online (Sandbox Code Playgroud)

要么

-ex {[sudo] password for subhasish:} {send "$password\r"}
Run Code Online (Sandbox Code Playgroud)


Sub*_*jee 6

谢谢格伦,现在可以了。它不起作用的另一个原因是它需要在正常登录和 sudo 登录之间休眠,否则在 $ 提示返回之前发送“sudo su”,供其他人参考,这里是代码,

#!/usr/bin/expect -f
#! /bin/bash

set timeout 60
log_user 1
set host *.*.*.*
set password ****** 
set user subhasish
set logfile output.txt
spawn ssh -p 10022 $user@$host
expect "*?assword:*"
send -- "$password\r"
#log_user 1
sleep 2
expect "$"
send -- "sudo su\r"
expect -gl {*password for subhasish:*}
send -- "$password\r"
expect "#"
send -- "service iptables status\r"
log_file /home/subhasish/output.log
expect "#"
log_file
send -- "exit\r";
send -- "exit\r";
exit 0
Run Code Online (Sandbox Code Playgroud)