2

過去 2 日間、頭を悩ませている問題が発生しました。

トリガーされるとローカルシェルコマンド(子プロセス)を実行するtclスクリプト(eggdrop用)を実行しています。コマンドが成功すると、結果が出力されます。ただし、コマンドが成功しない場合は、エラーが発生します " Tcl error [proc_ports]: child process exited abnormally:.

子プロセスが結果を見つけられなかった場合、私が望むのはカスタム応答を作成することです。

スクリプトは次のとおりです。

set chan "#help"
bind pub -|- .port proc_ports

proc proc_ports {nick host handle channel testes} {
    global chan
    if {"$chan" == "$channel"} {
        return 0
    }

    if [matchattr $nick |fmn $channel] {
        set ports [lindex $testes 0]
        set fp [ exec grep -w "$ports" scripts/ports | awk {{$1=""; print $0}} ]

        putserv "PRIVMSG $channel :Port \002$ports\002 is normally used for: \002$fp\002"

        return 1
    } else {
        putserv "PRIVMSG $channel :$nick, you do \002NOT\002 have access to this command!"
        return 1
    }
}

execをエラーを返すシェルスクリプトに変更するのではなく、TCLを使用してこれを解決し、詳細を学びたいと思います。

私はTCLのCATCHコマンドを読み、スクリプトに対してさまざまなアプローチを試みましたが、すべて失敗しました:(

どんな助けでも大歓迎です。

乾杯。

4

2 に答える 2

4
  1. 大きなセキュリティ上の問題があります。1a) 変数「testes」には、ユーザーの TEXT が含まれます。「testes」には有効な TCL リストが含まれていると見なし、「lindex」を使用します。少なくともコマンドset ports [lindex [split $testes] 0] 1b) を使用する必要があります。シェルで実行するカスタム テキストを送信する前に、不正な文字が含まれていないかどうかを確認する必要があります。string isregexp、を使用しregsubます。

  2. コマンドの実行でエラーをチェックするには、次のコードを使用できます。

    set ports [lindex $testes 0]
    if { [catch {exec grep -w "$ports" scripts/ports | awk {{$1=""; print $0}}} fp] } {   
      putserv "PRIVMSG $channel :Something wrong while executing command."
    } {
      putserv "PRIVMSG $channel :Port \002$ports\002 is normally used for: \002$fp\002"
    }
    
于 2013-02-10T13:04:35.027 に答える
3

ここにはいくつかの問題があります。まず、実行するパイプラインが に書き込まexecにゼロ以外の終了コードで終了すると、そのようなエラー メッセージが生成されます。次に、何も見つからない場合の終了コードは 1 です。これらの 2 つの機能は、うまく組み合わせることはできません。stderrgrep

最も簡単な修正はこれを行うことです:

if {[catch {
    set fp [ exec grep -w "$ports" scripts/ports | awk {{$1=""; print $0}} ]
    putserv "PRIVMSG $channel :Port \002$ports\002 is normally used for: \002$fp\002"
}]} {
    putserv "PRIVMSG $channel :Port \002$ports\002 not in port database"
}

catchエラーが発生した場合は結果として 1 が返され、エラーが発生しなかった場合は 0 が返されるため、これは機能します。すべてのエラーは、何も見つからなかった結果であると想定します (良いアイデアではありませんが、便利です!)。しかし、それが気になる場合は、Tcl 8.6 のtryコマンドの方がより明確です。

于 2013-02-10T13:06:17.810 に答える