如何从UNIX

时间:2019-02-11 23:14:10

标签: expect spawn

基于此处发布的主题之一,我设计了我的期望脚本以返回退出代码,但由于某种原因,该脚本可以继续运行并且根本不退出

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

下面是编写的代码

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 :(得分: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退出第二个脚本而不是第一个脚本作为警告标志为事实。)

答案 1 :(得分: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

因此,我期望生成期望脚本向我的调用.sh脚本返回非0的退出代码。

我可能忘了提到我的主要脚本是.sh。在其中,我正在调用带有我发布的上述命令的Expect脚本。

.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

基于返回代码,我希望计划自己的进一步行动。

关于, 艾伦