如何从unix中的expect / spawn命令获取退出代码

问题描述 投票:-2回答:2

根据这里发布的主题之一,我设计了我的期望脚本来返回退出代码但由于某种原因它继续运行并且根本没有退出

我使用以下脚本从远程服务器中获取文件 - 在传输完成后删除文件

下面是编写的代码

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

问候,艾伦

expect spawn
2个回答
3
投票

对于您的第一个脚本:

它应该退出返回代码。

你需要告诉催生的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退出第二个脚本但不是第一个作为警告标志。)


0
投票

阿德里安,

我修改了脚本如下

[...]

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 expect脚本将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

根据返回代码,我希望计划我的进一步行动。

问候,艾伦

© www.soinside.com 2019 - 2024. All rights reserved.