LINUX.ORG.RU

Помогите с TCL, пожалуйста


0

0

Вечер добрый
Раньше никогда программ не писал, решил попробовать
Есть вот такой скрипт:

#! /usr/bin/wish8.4

package require fileutil
package require BWidget
proc ping {ipinput packinput} {
global a
set a 1
    .top.t insert end "Ping $ipinput:\n"
	if {$packinput==""} {
	    set packinput 5
	}
    for {set i 0} {$i!=$packinput} {incr i} {
    exec ping -nc 1 $ipinput > ping
    set text [string replace [lindex [fileutil::grep "bytes from" ping] 0] 0 6]
    .top.t insert end $text\n
    .top.t see end
    if {$a==0} {
    break
    }
    update
  }
}

toplevel .top -width 370 -height 300

entry .top.e1 -width 15 -textvariable ipinput
entry .top.e2 -width 5 -textvariable packinput
label .top.ip -text IP:
label .top.count -text Packets:
button .top.b1 -text "Ping" -command {ping $ipinput $packinput}
button .top.b2 -text "Quit" -command exit
button .top.b3 -text "Stop" -command {set a 0}
text .top.t -width 60 -height 9 -relief sunken -bd 2
place .top.t -x 0 -y 100
place .top.e1 -x 50 -y 2
place .top.e2 -x 50 -y 30
place .top.ip -x 0 -y 2
place .top.count -x 0 -y 30 
place .top.b1 -x 5 -y 70
place .top.b3 -x 75 -y 70
place .top.b2 -x 135 -y 70

За исполнение больно не бить
Вопрос - почему при отсутствующем пинге до адреса, форма перестает реагировать на кнопки, а потом случается child process exited abnormally?
И что это за второе окошко при запуске?
anonymous

У тебя команда ping висит в ожидании ответа. А два окна: одно это . - создаваемое автоматически, а второе - .top , созданное в программе.

Morgendorffer
()
Ответ на: комментарий от Morgendorffer

to Morgendorffer:

А кошерно ли тогда будет писать вот так:
catch {exec ping -w 1 -nc 1 $ipinput > ping} ?
И нужно ли каждый раз на любую возможную ошибку прицеплять catch?

anonymous
()
Ответ на: комментарий от anonymous

> А кошерно ли тогда будет писать вот так: catch {exec ping -w 1 -nc 1 $ipinput > ping} ?

Это не просто кошерно, это труъ.

> И нужно ли каждый раз на любую возможную ошибку прицеплять catch?

По-моему, глупый вопрос. Хороший программист всегда должен проверять возможные ошибки.

gaa ★★
()

> Вопрос - почему при отсутствующем пинге до адреса, форма перестает реагировать на кнопки

используй blt::bgexec

gaa ★★
()
Ответ на: комментарий от gaa

> используй blt::bgexec

поподробнее:

blt::bgexec используется в основном для выполнения заданий в фоне(для этого в конце команды надо ставить &). вывод можно обрабатывать последовательно.

вот пример-звонилка(запускает pon $provider), думаю в твоём случае он будет полезен:

#!/bin/sh
# \
exec wish "$0" "$@"

package require BLT

set connectString {pon $provider}
set runLicq 1
set runPsi 1

if {$argc != 1} {
puts "You must specify provider's name as the first argument"
exit
} else {
set provider [lindex $argv 0]
}

wm title . "Connecting to ${provider}"
label .status -text "Connecting... "
pack .status
checkbutton .checkRunLicq -text "Run Licq" -variable runLicq
checkbutton .checkRunPsi -text "Run Psi" -variable runPsi
pack .checkRunLicq
pack .checkRunPsi

set f [frame .frame]
button $f.cancel -text "Cancel" -command {
set statusVar 0
exit
}
button $f.details -text "Details" -command showDetails
pack $f.cancel $f.details -side left
pack $f

text .details -yscrollcommand ".scroll set" -setgrid true -width 70 -height 32 -wrap word
scrollbar .scroll -command ".details yview"

.details tag configure error -foreground red

proc showDetails {} {
pack .scroll -side right -fill y
pack .details -expand yes -fill both
}

proc outHandler {args} {
.details insert end "[join $args]\n"
.details yview moveto 1.0
}

proc errHandler {args} {
.details insert end "[join $args]\n" error
.details yview moveto 1.0
}

if [catch {blt::bgexec statusVar -onoutput outHandler -onerror errHandler -linebuffered true /bin/sh -c [subst ${connectString}]}] {
.status configure -text "Failed"
} else {
.status configure -text "Success"
if { $runLicq } {
exec licq &
}
if { $runPsi && [ catch {exec pgrep psi > /dev/null} ] } {
exec psi &
}
after 2
exit
}

gaa ★★
()
Ответ на: комментарий от gaa

to gaa:

Спасибо, я как раз пытался выяснить, почему с catch форма доступна, но реагирует раз в секунду и нажатие кнопки стоп визуально не отрабатывается.

Пример хорош, Clif Flynt таких писать не умеет.

Буду баловаться дальше

anonymous
()
Ответ на: комментарий от gaa

> Это меня так обхамили или похвалили? ;)

Спасибо сказали,да
Я просто устал продираться через бессмысленные строки Флинтовского
Developer`s guide`а

А скажи, какие пакеты принято считать полезными?
У меня стоят tcllib, blt, mysqltcl, BWidget.
Иногда для смеха пользуюсь ActiveState`овским дебагером.
Посмотрел TCLsc - похоже, что проще ничего нет.

anonymous
()
Ответ на: комментарий от anonymous

конкретно этот пример можно попробовать переписать на expect, там проще с фоновыми процессами и корректными тестами (пишешь в стиле: ожидается выхлоп такой-то, запускается действие такое-то. Проще сопровождать единообразно, если на другой системе ping что-то другое выдаст).

Хотя и без него просто получается, пример простой.

anonymous
()
Ответ на: комментарий от anonymous

В идеале, в этом скрипте, если он будет работать часто, самое медленное место -- порождение нового процесса ping (ну если часто этот скрипт будет запускаться). От этого можно избавиться -- написать простое С приложение с встроенным Tcl/Tk, сделать ping С функцией, экспортированной в команду Tcl, запускать из С приложения этот Tcl/Tk скрипт. Можно взять готовый пример про встраивание Tcl в C приложение, пустую болванку и совсем чуть-чуть допилить.

anonymous
()
Ответ на: комментарий от anonymous

> А скажи, какие пакеты принято считать полезными? У меня стоят tcllib, blt, mysqltcl, BWidget.

Сложно сказать. blt - очень мощная вещь, в ней много полезного. Есть неплохой набор виджетов iwidgets. Ещё стоит вспомнить tclxml для интеграции с модным xml-ем.

PS. И не стоит забывать tk :)

gaa ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.