Re: Gracefully stopping an infinite loop after a particular keyboard input
- From: Glenn Jackman <glennj@xxxxxx>
- Date: 15 Dec 2006 14:45:43 GMT
At 2006-12-15 04:23AM, "Ranjan" wrote:
I am having a script that is doing some tests continuously. I am
running it from cygwin under Windows OS and is currently using CTRL+C
to stop the script. But by "ctrl+c" the script stops at that very
moment. In between there are some read write operations going on files
and when the script stops atonce.
I want that when I press any key say "Q" from keyboard , the script
should complete that particular loop and then stop. (Hope I am able to
clarify my problem).
The following will work if it's OK that the users type "Q<Enter>":
while {1} {
# do stuff
set char [read stdin 1]
if {[string tolower $char] eq "q"} {
break
}
}
If you want just "q" with no "Enter", you have to put your terminal
into a special state and use the event loop: (this won't work on
Windows)
proc main {} {
# cook the tty
set old_tty [exec stty -g]
exec stty -echo -icanon min 0
fconfigure stdin -buffering no -blocking no
fileevent stdin readable [list readStdin]
after 100 do_stuff
vwait ::forever
# restore the tty:
exec stty $old_tty
}
proc do_stuff {} {
# this is your while-loop body
after 100 do_stuff
}
proc readStdin {} {
set char [read stdin 1]
if {[string tolower $char] == "q"} { set ::forever now }
}
main
I wrote the following script that polls vmstat or top to display memory
usage. The user will his 'q' to exit:
################################################################################
#!/bin/sh
#
# $Id: freemem,v 1.2 2005/10/12 14:47:12 xx087 Exp $
# $Source: /usr/local/src/ncf/cvsroot/glennj/freemem,v $
#
# \
exec tclsh "$0" ${1+"$@"}
#HELP# Display free memory and free swap.
#HELP# usage: $0 [-h] [-t|-v]
#HELP# where: -t use memory info from 'top' (default)
#HELP# -v use memory info from 'vmstat'
#
lappend auto_path /export/home/glennj/tcl/lib
package require cmdline
package require miscutil
proc main {argc argv} {
set service [parseArgs $argv]
# cook the tty
set old_tty [exec stty -g]
exec stty -echo -icanon min 0
fconfigure stdin -buffering no -blocking no
fileevent stdin readable [list readStdin]
# unbuffer stdout
fconfigure stdout -buffering none
# start the background pipe
switch -exact $service {
vmstat { set pipe [open "|vmstat 1" r]; set ::count 0 }
top { set pipe [open "|top -u -b -d300 -s1" r] }
}
fconfigure $pipe -buffering line
fileevent $pipe readable [list handle $pipe $service]
puts "hit 'q' to quit:"
vwait ::forever
exec stty $old_tty
puts ""
}
proc parseArgs {argv} {
set service top
while {[set err [cmdline::getopt argv {h t v} opt val]] > 0} {
switch -- $opt {
h {helpme}
t {set service top}
v {set service vmstat}
}
}
if {$err < 0} {
puts stderr $val
helpme stderr
}
return $service
}
proc helpme {{chan stdout}} {
set whoami [info script]
set 0 [file tail $whoami]
set fid [open $whoami r]
while {[gets $fid line] != -1} {
if {[regexp {^#HELP# (.*)} $line -> text]} {
puts $chan [subst -nocommands $text]
}
}
close $fid
set rc 0
if {$chan == "stderr"} {set rc 1}
exit $rc
}
proc handle {chan app} {
if {[gets $chan line] == -1} {
close $chan
set ::forever now
} else {
switch -exact $app {
top {handle_top $line}
vmstat {handle_vmstat $line}
}
}
}
proc handle_vmstat {line} {
if {[incr ::count] <= 3} return ;# ignore the first couple of lines
if {[regexp -- {^[ \t]*[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+([0-9]+)[ \t]+([0-9]+)} $line -> swap free]} {
puts -nonewline "\rfree mem: [miscutil::commify $free] KB,\tfree swap: [miscutil::commify $swap] KB "
}
}
proc handle_top {line} {
if {[regexp {^Memory} $line]} {
puts -nonewline "\r$line"
}
}
proc readStdin {} {
set char [read stdin 1]
if {[string tolower $char] == "q"} { set ::forever now }
}
main $argc $argv
################################################################################
--
Glenn Jackman
Ulterior Designer
.
- Follow-Ups:
- References:
- Prev by Date: Re: about the canvas widget
- Next by Date: Re: which tcllib version for tcl 8.0
- Previous by thread: Re: Gracefully stopping an infinite loop after a particular keyboard input
- Next by thread: Re: Gracefully stopping an infinite loop after a particular keyboard input
- Index(es):
Relevant Pages
|