Проблеми с разбирането на TCL CATCH exec проблем

Имам проблем, който ме тормози през последните 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
    }
}

Бих искал да реша това с помощта на TCL, за да ми помогне да науча повече, вместо да променям exec в скрипт на обвивка, който би върнал всякакви грешки.

Прочетох информация за командата CATCH в TCL и опитах много различни подходи към скрипта, но всичките ме провалиха :(

Всяка помощ ще бъде оценена.

наздраве


person Instronics    schedule 10.02.2013    source източник


Отговори (2)


  1. Имате ОГРОМЕН проблем със сигурността. 1a) Променливата "тестиси" съдържа потребителски ТЕКСТ. Вие смятате, че „тестисите“ съдържа валиден TCL списък и използвате „lindex“ в него. Трябва да използвате поне команда set ports [lindex [split $testes] 0] 1b) Преди да изпратите персонализиран текст за изпълнение в shell, трябва да проверите дали съдържа непозволени знаци. Използвайте string is, regexp, regsub.

  2. #P2#
    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"
    }
    
person Chpock    schedule 10.02.2013
comment
Бих използвал regexp {\w+} $testes ports, за да хвана първата дума (тествайки нейния резултат, за да видя дали изобщо няма съвпадение). Ще направи правилното нещо във всички случаи, които наистина искате да подкрепите. - person Donal Fellows; 10.02.2013
comment
Макар и двете решения да работят като чар за мен (благодаря на всички), бих искал да благодаря на Chpock за това, че посочи проблема със сигурността. В момента не съм МНОГО притеснен за това, тъй като много внимавам кой има достъп до eggdrop (flags fmn). Но като цяло да, трябва да приложа това, което споменахте от съображения за сигурност, и ще го направя. наздраве - person Instronics; 10.02.2013

Тук има няколко проблема. Първо, 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, ако е нямало грешка. Ще приемем, че всички грешки са резултат от ненамиране на нищо (не е страхотна идея, но удобна!), но ако това ви притеснява, командата try на Tcl 8.6 е по-дискриминираща.

person Donal Fellows    schedule 10.02.2013
comment
Най-общо казано, бих се опитал да избягвам да правя grep/awk всеки път. Задържането на това картографиране в работещата Tcl програма (например в асоциативен масив) би било по-бързо и по-безопасно. Но кодът за това е по-радикална промяна, така че ще отида с минималния хак. - person Donal Fellows; 10.02.2013
comment
Благодаря ви много, вашето решение също работи като чар :) - person Instronics; 10.02.2013