期望脚本中的退出处理程序不删除文件

时间:2015-06-03 21:25:58

标签: linux expect signal-handling exit-handler

我正在写一篇关于期望剧本的麻烦。该脚本的目标是SSH到合作伙伴并获取网络配置信息。该信息保存在文件中并复制回本地主机进行处理。然后在退出时从远程主机中删除该文件。

在正常情况下,一切都很好,正如我所料。但是,如果用户在SCP进程期间按^ C中断脚本,则不会从远程主机中删除该文件。它留在那里。我不知道为什么会这样或者如何强制它被删除。在这种情况下单步执行我的信号处理程序和退出处理程序时,似乎出于某种原因,退出处理程序并不认为该文件存在并跳过if语句。我不知道为什么。

我从下面的脚本中复制了退出处理程序和信号处理程序。如果您有任何想法或看到任何明显的错误,请告诉我。我不确定从哪里开始。

# Configure exit handler
exit -onexit {
    # Remove configuration info file if it exists 
    if {[file exists ptinit.txt]} {
        send "rm -rf ptinit.txt\r"
        expect -exact "rm -rf ptinit.txt\r"
    }
}

# Configure signal trap to remove partner file before exiting
proc errsig_handler {pidlst} {
    send_user "\nStop command received from user. Exiting.\n"

    for {set i [expr [llength $pidlst]-1]} {$i >= 0} {incr i -1} {
        send_user "Current PID is: [lindex $pidlst $i]\n"

        # If pid is not null and process is currently running, kill it
        if {[lindex $pidlst $i] != "" && [exec kill -0 [lindex $pidlst $i] 2>/dev/null] == ""} {
            send_user "PID [lindex $pidlst $i] is not null and is currently running.\n"
            exec kill -9 [lindex $pidlst $i]
        }
    }
}

trap {errsig_handler $cur_pid} {INT TSTP}

更新 我尝试了Dinesh建议的方法,但仍然有问题。我更新了退出处理程序代码,如下所示: exit -onexit {     exp_internal 1     unset expect_out(buffer)

# Remove configuration info file from remote server 
send_user "\nIN EXIT HANDLER\n"

send "rm -rf ptinit.txt\r"
expect {
    "rm -rf ptinit.txt\r" {
        sleep 5
        send "exit\r"
        expect eof {puts "EOF in rm match received."; sleep 2}
    }
    "cannot remove" { 
        puts "File deletion was not successful - ptinit.txt needs to be deleted manually."
    }
    -re $prompt {
        sleep 5
        send "exit\r"
        expect eof {puts "EOF received."; sleep 2}
    }
}

send_user "LEAVING EXIT HANDLER\n"

}

我能让它工作的唯一方法是通过注释我的信号处理程序for循环来杀死生成的PID。取消注释时,退出处理程序会超时。

无论哪种方式,文件仍然不会从远程系统中删除。这是我从exp_internal 1中看到的:

Stop command received from user. Exiting.

IN EXIT HANDLER
send: sending "rm -rf ptinit.txt\r" to { exp9 }
Gate keeper glob pattern for '(%|#|>|\$) $' is ''. Not usable, disabling the performance booster.

expect: does " \r\n" (spawn_id exp9) match glob pattern "rm -rf ptinit.txt\r"? no
"cannot remove"? no
"(%|#|>|\$) $"? (No Gate, RE only) gate=yes re=no

expect: does " \r\nrm -rf ptinit.txt\r\n" (spawn_id exp9) match glob pattern "rm -rf ptinit.txt\r"? yes
expect: set expect_out(0,string) "rm -rf ptinit.txt\r"
expect: set expect_out(spawn_id) "exp9"
expect: set expect_out(buffer) " \r\nrm -rf ptinit.txt\r"
send: sending "exit\r" to { exp9 }
expect: read eof
expect: set expect_out(spawn_id) "exp9"
expect: set expect_out(buffer) "\n\rptinit.txt                                      0%    0     0.0KB/s   --:-- ETA\rptinit.txt
                               100%   35     0.0KB/s   00:00    \r\nexit\r\n"
EOF in rm match received.
LEAVING EXIT HANDLER
tty_set: raw = 5, echo = 0

更新2:

我将退出处理程序更新为以下内容:

exit -onexit {
    exp_internal 1
    unset expect_out(buffer)

    # Remove configuration info file from remote server 
    set filename ptinit.txt
    send_user "\nIN EXIT HANDLER\n"

    send "rm -rf $filename\r"
    expect {
        "cannot remove" { puts "File deletion is not successful" }
        -re $prompt { puts "File deleted" }
    }
    send_user "LEAVING EXIT HANDLER\n"
}

这是调试信息 - 仍然没有删除文件。

Stop command received from user. Exiting.

IN EXIT HANDLER
send: sending "rm -rf ptinit.txt\r" to { exp9 }
Gate keeper glob pattern for '(%|#|>|\$) $' is ''. Not usable, disabling the performance booster.

expect: does " \r\n" (spawn_id exp9) match glob pattern "cannot remove"? no
"(%|#|>|\$) $"? (No Gate, RE only) gate=yes re=no

expect: does " \r\nrm -rf ptinit.txt\r\n" (spawn_id exp9) match glob pattern "cannot remove"? no
"(%|#|>|\$) $"? (No Gate, RE only) gate=yes re=no

expect: does " \r\nrm -rf ptinit.txt\r\n\rptinit.txt                                      0%    0     0.0KB/s   --:-- ETA" (spawn_id
 exp9) match glob pattern "cannot remove"? no
"(%|#|>|\$) $"? (No Gate, RE only) gate=yes re=no

expect: does " \r\nrm -rf ptinit.txt\r\n\rptinit.txt                                      0%    0     0.0KB/s   --:-- ETA\rptinit.tx
t                                    100%   35     0.0KB/s   00:00    \r\n" (spawn_id exp9) match glob pattern "cannot remove"? no
"(%|#|>|\$) $"? (No Gate, RE only) gate=yes re=no
expect: read eof
expect: set expect_out(spawn_id) "exp9"
expect: set expect_out(buffer) " \r\nrm -rf ptinit.txt\r\n\rptinit.txt                                      0%    0     0.0KB/s   --
:-- ETA\rptinit.txt                                    100%   35     0.0KB/s   00:00    \r\n"
LEAVING EXIT HANDLER
tty_set: raw = 5, echo = 0

1 个答案:

答案 0 :(得分:0)

问题在于file exists。它会检查本地计算机中存在与否的文件路径,无论您在哪里运行Expect脚本,都不在远程目录中。

删除它将解决问题。

#This is a common approach for few known prompts
#If your device's prompt is missing here, then you can add the same.
set prompt "#|>|\\\$"; # We escaped the `$` symbol with backslash to match literal '$'

set filename ptinit.txt
send "rm -rf $filename\r"
expect {
    "cannot remove" { puts "File deletion is not successful"}
    -re $prompt { puts "File deleted" }
}

更新 在您的代码中,您期望rm -rf ptinit.txt\r出错。因为expect会看到发送到生成进程的内容(也是rm -rf ptinit.txt\r)并与之匹配。因此,它从未实际发送到生成的进程。

那么,你能为我提供的上述代码启用调试并在这里分享吗?