Как получить код выхода из команды Exak / Spawn в Unix - PullRequest
0 голосов
/ 12 февраля 2019

Основываясь на одной из опубликованных здесь тем, я разработал свой ожидаемый сценарий, который возвращает код завершения, но по какой-то причине он продолжает работать и вообще не завершается

Я использую приведенный ниже сценарий для -получить файл с удаленного сервера - удалить файл после завершения передачи

Ниже приведен код

set timeout 30

set user [lindex $argv 0]
set pass [lindex $argv 1]
set host [lindex $argv 2]
set remote_file [lindex $argv 3]
set local_file [lindex $argv 4]
set port [lindex $argv 5]

if {$port != "" } {
spawn sftp -oPort=$port $user@$host
} else {
spawn sftp $user@$host}
expect -nocase password:
send "$pass\r"
expect sftp>

send "get $local_file $remote_file\r"
expect sftp>

send "rm $local_file\r"
expect eof

set waitval [wait -i $spawn_id]
exit [lindex $waitval 3]

-> Должен завершиться выход с кодом возврата.

Я сейчас использую альтернативный скрипт ниже.Оно работает.Но я надеялся сделать его более общим, не упоминая сообщения об ошибках.Пожалуйста, дайте мне знать, если есть какие-либо улучшения, которые могут быть сделаны для приведенного ниже сценария.

set timeout 30

set user [lindex $argv 0]
set pass [lindex $argv 1]
set host [lindex $argv 2]
set remote_file [lindex $argv 3]
set local_file [lindex $argv 4]
set port [lindex $argv 5]

if {$port != "" } {
spawn sftp -oPort=$port $user@$host
} else {
spawn sftp $user@$host}
expect -nocase password:
send "$pass\r"
expect {
-re "failed|invalid password|incorrect|denied" {exit 1}
"Connection closed" {exit 1}
timeout {exit 1}
"sftp>"
}

send "get $local_file $remote_file\r"
expect {
-re "not found|denied|error|failure" {exit 1}
"No such file or directory" {exit 1}
timeout {exit 1}
"sftp>"
}

send "rm $local_file\r"
expect {
-re "not found|denied|cannot remove|error|failure" {exit 1}
"No such file or directory" {exit 1}
"sftp>"
}

send "exit\r"
expect eof

С уважением, Аллен

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Адриан,

Я изменил скрипт, как показано ниже

[...]

send "rm $local_file\r"
expect sftp>

send "exit\r"

set waitval [wait -i $spawn_id]
exit [lindex $waitval 3]

Я протестировал сценарий файла, которого нет в нашей целевой системе, и ниже выводится его

sftp> get /pw/work/outbound/SendBills*.zip /pw/work/inbound/ar/
File "/pw/work/outbound/SendBills*.zip" not found.

sftp> rm /pw/work/outbound/SendBills*.zip
Removing /pw/work/outbound/SendBills*.zip
Couldn't delete file: No such file or directory

Итак, я ожидал, что сценарий spawn Ожидает возврата кода завершения, отличного от 0, в мой вызывающий сценарий .sh.

Возможно, я забыл упомянуть, что мой основной сценарий - .sh.В нем я вызываю сценарий ожидающего, который содержит приведенные выше команды.

Команда из моего сценария .sh:

if [ "$PSWD" = "Y" ]
then

$PS_APP_HOME/az/scripts/sh/azstmtsftp.exp $USER $PASS $HOST $REMOTE $LOCAL $PORT --   Here is where I am calling the expect script

else 

--This was written in case the third pary goes for SSH keys in future
sftp  $USER@$HOST  <<EOF
get $LOCAL $REMOTE
rm $LOCAL

EOF
fi

RETCODE=$?

Я надеялся, что $ RETCODE будет иметькод завершения ошибки (из моего ожидаемого сценария), а не 0

Исходя из кода возврата, я надеялся спланировать свои дальнейшие действия.

С уважением, Аллен

0 голосов
/ 12 февраля 2019

Для вашего первого сценария:

Он должен иметь выход с кодом возврата.

Вам необходимо сообщить порожденный sftpчтобы выйти, иначе wait ждет вечно:

[...]
send "get $local_file $remote_file\r"
expect sftp>

send "rm $local_file\r"
expect sftp>

send "exit\r"

set waitval [wait -i $spawn_id]
exit [lindex $waitval 3]

Что касается второго сценария, я бы как минимум определил proc, который изящно завершает работу при условии ошибки, вместо просто exit 1 снет объяснения.Примерно так:

# Lets user know what went wrong, then gracefully stop sftp
proc err_exit {msg} {
  puts stderr "ERROR: $msg, aborting."
  send "exit\r"
  expect eof
  exit 1
}
[...]
expect {
  -re "failed|invalid password|incorrect|denied" {
    err_exit "Access denied"
  }
  "Connection closed" {
    err_exit "sftp connection closed unexpectedly"
  }
  timeout {
    err_exit "Timeout occurred"
  }
  "sftp>"
}

О, и ваш код серьезно нуждается в правильном отступе и выравнивании.Tcl не волнует, но понимание кода затруднено без него.(Возьмем тот факт, что вы сказали sftp выйти во втором сценарии, но не в первом, как предупреждающий знак.)

...