了解TCL CATCH exec问题的问题

时间:2013-02-10 11:50:31

标签: exec try-catch tcl eggdrop

在过去的两天里遇到了问题。

我正在运行一个tcl脚本(用于eggdrop),当触发时,执行本地shell命令(子进程),如果命令成功,则会吐出结果。但是,如果命令不成功,我会收到错误“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
    }
}

我很乐意使用TCL解决这个问题,以帮助我了解更多内容,而不是将exec更改为可以返回任何错误的shell脚本。

我已经阅读了TCL中的CATCH命令,并尝试了许多不同的脚本方法,但都让我失望:(

任何帮助都将不胜感激。

干杯。

2 个答案:

答案 0 :(得分:4)

  1. 您遇到了巨大的安全问题。 1a)变量“testes”包含用户TEXT。您认为“testes”包含有效的TCL列表并在其上使用“lindex”。你应该至少使用命令set ports [lindex [split $testes] 0] 1b)在发送自定义文本以在shell中运行之前,您应该检查它是否包含非法字符。使用string isregexpregsub

  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"
    }
    

答案 1 :(得分:3)

这里有一些问题。首先,exec在运行它的管道以非零退出代码退出而不写入stderr时会产生这种错误消息。其次,grep在没有找到任何内容时退出代码为1。这两个功能并不能很好地结合在一起!

最简单的解决方法是:

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命令更具辨别力。