0

私が書いている期待スクリプトに問題があります。スクリプトの目的は、パートナーに SSH で接続し、ネットワーク構成情報を取得することです。その情報はファイルに保存され、処理のためにローカル ホストにコピーされます。ファイルは、終了時にリモート ホストから削除されます。

通常の状態では、すべてがうまく機能し、期待どおりです。ただし、ユーザーが ^C を押して SCP プロセス中にスクリプトを中断した場合、ファイルはリモート ホストから削除されません。そこに残されています。これがなぜなのか、強制的に削除する方法がわかりません。このような場合にシグナル ハンドラーと終了ハンドラーをステップ実行すると、何らかの理由で終了ハンドラーがファイルの存在を認識せず、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"

}

これを機能させる唯一の方法は、生成された 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
4

1 に答える 1

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) に送信されたものを確認し、それと一致するためです。このため、生成されたプロセスに実際に送信されることはありません。

それで、私が提供した上記のコードのデバッグを有効にして、ここで共有できますか?

于 2015-06-04T05:44:41.477 に答える