Ожидается, что скрипт не завершается с кодом, который я установил - PullRequest
0 голосов
/ 31 марта 2020

Я попытался опубликовать это в сообществе codereview, но нет ожидаемого тега, и у меня недостаточно кармы для создания тегов.

Я написал ожидаемый сценарий для входа на сервер или запуска простая (обычно одиночная) команда и возвращает результат.

У меня две проблемы и одна команда wi sh.

  • , которая ничего не возвращает - т.е. ssh2server user host false - время ожидания с ошибкой (потому что я не фиксирую время ожидания, хотя я полагаю, что должен) вместо того, чтобы просто ничего не возвращать.
  • Я могу захватить код возврата программы, но не могу его получить для выхода с соответствующим кодом.
  • Есть ли способ, которым я могу взять вывод вызванной программы и вернуть его таким же образом (удаленный стандартный вывод идет в локальный стандартный вывод, а удаленный стандартный вывод - в локальный стандартный)?

Также, любые комментарии или (конструктивная) критика будут приветствоваться.

 #!/usr/bin/expect -f

 if {[info exists ::env(SSH2SERVER_PASSWORD)]} {
   set password "$env(SSH2SERVER_PASSWORD)"

 } else {
   puts "SSH2SERVER_PASSWORD not set"
   exit 1
 }

 if {[llength $argv] < 2} {
   puts "usage: ssh2server user server"
   exit 1
 }

 set user    [lindex $argv 0]
 set server  [lindex $argv 1]
 set command [lrange $argv 2 end]

 set pwd_prompt "*assword:"
 set prompt "\$ "

 set rc 0

 expect_before {
   #timeout { send_user 'timeout' ; exit 2 }
   timeout { send_user 'timeout' ; set rc 2}
 }

 log_user 0
 spawn ssh $user@$server
 expect "$pwd_prompt" { send -- "$password\r" }

 if { $command == "" } {
   interact

 } else {
   expect {
     "$prompt" {
       send -- "PROMPT_COMMAND=\rPS1='_MYPROMPT_'\r$command\r"
       #expect -re "$command\r\n(.*)\r\n\[^\r]*\[#\$%]"
       expect -re "$command\r\n(.*)\r\n\[^\r]*_MYPROMPT_"
       set results $expect_out(1,string)
       puts $results
       send -- "^D"
       expect eof
       #catch wait ec
       #set rc [lindex $ec 3]
       #puts [lindex $ec 3]
       #exit [lindex $ec 3]
     }

     #eof { send_user $expect_out(buffer); exit 3}
     eof { send_user $expect_out(buffer); set rc 3}
   }
 }

 log_user 1

 lassign [wait] pid spawnid os_flag rc
 #puts $rc # outputs correct value
 exit $rc

1 Ответ

1 голос
/ 31 марта 2020

Я подозреваю, что это проблема:

       send -- "^D"

Вы не отправляете Ctrl-D, вы отправляете символы ^ и D .

Чтобы отправить Ctrl-D

       send -- "\04"

Чтобы решить проблему «без вывода, время ожидания», вам нужно изменить ожидаемое регулярное выражение: у вас слишком много новых строк для этого случая , Использование expect -d показало бы это вам. Например:

       send -- "unset PROMPT_COMMAND; PS1='_MYPROMPT_'\r"
       expect -re "_MYPROMPT_$"

       send -- "$command\r"
       expect -re "$command(.*)\r\n_MYPROMPT_$"

Содержимое захватывающих скобок теперь может быть пустым.

Я отключил установку подсказки для ясности.


Для захвата Для выхода из состояния команды вам может потребоваться сделать следующее:

       send -- "$command; echo $?\r"
       expect -re "$command(.*)\r\n(\d+)\r\n_MYPROMPT_$"

       set results [regsub {^\r\n} $expect_out(1,string) ""]
       set status $expect_out(2,string)

Я не думаю вы можете разделить stdout и stderr с помощью команды expect. Я думаю, что оба потока захвачены как "выходные данные". (У меня поблизости нет моей книги «Ожидаем исследования»)

Если это важно, вы можете вызвать команду, перенаправляющую stdout и / или stderr в файл (ы), а затем cat и захватить содержимое файла.

...