在过去的两天里遇到了问题。
我正在运行一个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命令,并尝试了许多不同的脚本方法,但都让我失望:(
任何帮助都将不胜感激。
干杯。
答案 0 :(得分:4)
您遇到了巨大的安全问题。
1a)变量“testes”包含用户TEXT。您认为“testes”包含有效的TCL列表并在其上使用“lindex”。你应该至少使用命令set ports [lindex [split $testes] 0]
1b)在发送自定义文本以在shell中运行之前,您应该检查它是否包含非法字符。使用string is
,regexp
,regsub
。
要检查命令执行中的错误,可以使用以下代码:
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
命令更具辨别力。