⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logview.tk

📁 《Beginning linux programming》一书相应的源代码
💻 TK
字号:
#!/usr/bin/wish -f# logView.tk  --#	#	Essentially a general purpose GUI wrapper to tail, gui and any commands#	that will output data continuosly. This GUI has the ability to record#	the commands as smart buttons, so that you can re-run the same commands#	again and again without having to retype  set tailRc "~/.tailrc"wm title .  "Process Log Viewer"wm iconname . "Log Viewer"global tailSize textw fileName tailFd curNick tailOpts statusImgWin# tailSize --> size in lines of tail output to display# fileName --> File name: variable# tailFd   --> proc fd or file fd of current tail process# curNick  --> current nick being shown; nick essentially a shortcut to a cmd.# tailOpts --> saved options# statusImgWin --> window showing what kind of error it is!set tailSize 20set fileName "/home/";     #include your own path here# file types for the file selection dialog box.set tailOpts(types) {   {"All files"                 *}   {"Text files"                {.txt .doc}      }   {"Text files"                {}           TEXT}   {"Tcl Scripts"               {.tcl}       TEXT}   {"C Source Files"            {.c .h}          }   {"All Source Files"          {.tcl .c .h}     }   {"Image Files"               {.gif}           }   {"Image Files"               {.jpeg .jpg}     }   {"Image Files"               ""    {GIFF JPEG}}}set tailOpts(wins) {}# Next, we will build the user interface. proc BuildTailGui {w} {    global tailSize textw fileName tailFd curNick tailOpts statusImgWin    global viewOptMenu    if {$w == "."} {       set w "";    }    # Build Menu for file    menu $w.menu -tearoff 0    # File menu    set m $w.menu.file    menu $m -tearoff 0    $w.menu add cascade -label "File" -menu $m -underline 0    $m add command -label "Add New ..." -command {AddNew} -underline 0    $m add command -label "Exit" -command {exit} -underline 0    # Edit Menu    set m $w.menu.edit    menu $m -tearoff 0    $w.menu add cascade -label "Edit" -menu $m -underline 0    $m add command -label "Delete Nicks.." -command {DeleteNicks} -underline 0    # Help Menu    set m $w.menu.help    menu $m -tearoff 0     $w.menu add cascade -label "Help" -menu $m -underline 0    $m add command -label "About..." -underline 0 -command {        tk_messageBox -parent . -title "Process Log Viewer" -type \        ok -message    "Tk Tail Tool \nby Krishna Vedati(kvedati@yahoo.com)"    } # The routine then adds a text widget to display the output of any log proces.# Next, the routine builds rows of widgets.    # Create status/error message window    frame $w.status  -relief sunken -bd 2    set statusImgWin [label $w.status.flag -bitmap info]    label $w.status.lab -textvariable statusText -anchor w -bg "wheat"    pack $w.status.flag -side left      pack $w.status.lab -side left -fill both -expand 1    # File name: entry panel    frame $w.file    label $w.file.label -text "File name:" -width 13 -anchor w    entry $w.file.entry -width 30 -textvariable fileName    button $w.file.choose -text "..." -command \        "set fileName \[tk_getOpenFile -filetypes \$tailOpts(types) \         -parent \[winfo toplevel $w.file\]\];"    button $w.file.button -text "Tail File" \       -command "AddToView  file \$fileName"    pack $w.file.label $w.file.entry -side left    pack $w.file.choose -side left -pady 5 -padx 10    pack $w.file.button -side left -pady 5 -padx 10    bind $w.file.entry <Return> " AddToView  file \$fileName"    focus $w.file.entry    # Command entry panel    frame $w.fileC    label $w.fileC.cLabel -text "Command:" -width 13 -anchor w    entry $w.fileC.cEntry -width 40 -textvariable command    label $w.fileC.nLabel -text "Nick:" -anchor w    entry $w.fileC.nEntry -width 15 -textvariable nick    button $w.fileC.add -text "Add" -command "AddToView \"command\"\         \$command \$nick;"    pack $w.fileC.cLabel $w.fileC.cEntry -side left    pack $w.fileC.nLabel -side left -pady 5 -padx 10    pack $w.fileC.nEntry -side left -pady 5 -padx 5    pack $w.fileC.add -side left -pady 5 -padx 5    # Option Menu command panel    frame $w.optF    label $w.optF.label -text "View:" -width 12 -anchor w    set viewOptMenu [tk_optionMenu $w.optF.optB curNick " "]    button $w.optF.stop -text "Stop" -command Stop    pack $w.optF.label -side left     pack $w.optF.optB -side left -pady 5    pack $w.optF.stop -side left -pady 5    # create text widget    frame $w.textf -bg red    text $w.textf.text -height [expr $tailSize] -xscrollcommand "$w.textf.scrollh set" \       -yscrollcommand "$w.textf.scrollv set" -bg lightblue    set textw $w.textf.text    scrollbar $w.textf.scrollh -orient horizontal -command "$w.textf.text xview"    scrollbar $w.textf.scrollv -orient vertical -command "$w.textf.text yview"    pack $w.textf.scrollv -side right -fill y -expand 1    pack $w.textf.scrollh -side bottom -fill x -expand 1    pack $w.textf.text -fill x -fill y -expand 1    # pack all the frames    [winfo toplevel $w.textf] configure -menu $w.menu    pack $w.status -side bottom -fill x -pady 2m    pack $w.file -side top -fill x -expand 1    pack $w.fileC -side top -fill x -expand 1    pack $w.optF -side top -fill x -expand 1    pack $w.textf -side top -fill x -fill y -expand 1}# Once the user sets up a command or a file-type nick, the TailFile method will get called.# This method makes sure that the specified file exists.# It creates the command  and opens it as a process.# Then, it binds a read event to the file descriptor and returns.# The read event will call TailUpdate every time the file identifier associated# with the process is readable.#  TailFile --#        #        Show the tail of the request file.##  Arguments:#        file name to be tailed.#        #  Results:#        The tail of the file is shown in the window.#proc TailFile { type file {nick ""}} {    global tailSize tailFd  textw curNick     set w $textw    catch {        fileevent $tailFd readable {}        close $tailFd        update    }    $w delete 1.0 end    if {$type == ""} {        $w insert end "Illegal type...";        return    }    if {$type == "file"} {        if {$file == ""} {            $w insert end "please specify a valid filename..."            return        }        if ![file exists $file] {            DeleteFromView $file            $w insert end "file $file does not exist..."            return        }        set nick $file    } elseif {$type == "command"} {        if {$file == ""} {            $w insert end "please specify a command..."            return        }    }    if {$type == "file"} {        set tailFd [open "|tail -f $file" r]        wm title [winfo toplevel $w] "Tail tool \[tail -f $file\]"    } elseif {$type == "command"} {        if [catch {set tailFd [open "|$file" r]}] {            SetStatus error  "can't execute command $file..."            DeleteFromView $nick            set curNick ""            return        }                wm title [winfo toplevel $w] "Tail tool \[tail |$file\]"    }          fconfigure $tailFd -blocking 0    set lines 0    fileevent $tailFd readable "TailUpdate \$tailFd"}# The TailUpdate procedure gets called as part of the event handler on the current log process read status.# When this procedure gets called, it collects the output from the process and inserts it into the text widget.# It also makes sure that at any given time, no more than $tailSize lines are shown in the text window.proc TailUpdate {fileFd} {   global textw curNick   global tailSize tailFd   set w $textw   if [eof $tailFd] {      fileevent $tailFd readable {}      $w insert end "Tailing \"$curNick\" done..."      return   }   set line [gets $tailFd]      $w insert end $line   $w insert end "\n"      set lines [lindex [split [$w index end] .] 0]   if {$lines == [expr $tailSize+1]} {      $w delete 1.0 2.0   }   $w yview moveto 1.0}# The Stop call-back is used to stop the current logProcess.# Stop the current tailing process.proc Stop {} {   global tailFd   set pid [pid $tailFd]   catch {exec kill -9 $pid}}# The AddNew procedure gets called every time the user adds a new shortcut.# It creates a simple GUI for the user to create a new command nick.#  AddNew --#    Add a new tail file to the system##  Arguments:#    none.#    #  Results:#    proc AddNew {args} {   toplevel .addnew    set w .addnew   wm title $w "Add new tail file..."      frame  $w.top     frame $w.sep -bd 2  -relief ridge   frame $w.bot    set k $w.top      label $k.name -text "Nickname for item:"    label $k.command -text "Command:"     grid $k.name -row 0 -column 0 -sticky e   grid $k.command -row 1 -column 0 -sticky e   entry $k.nameE -textvariable nameE -width 40   entry $k.commandE -textvariable commandE -width 50   grid $k.nameE -row 0 -column 1 -sticky ew   grid $k.commandE -row 1 -column 1 -sticky ew      grid columnconfigure $k 1 -weight 1   grid propagate $k 1   pack $w.top  -side top -fill both -expand 1   pack $w.sep -side top -fill x -expand 1 -pady 5   pack $w.bot -side top -fill x -expand 1      button $w.bot.apply -text "Add" -command "AddToView \"command\"  \"\$commandE\" \"\$nameE\""   button $w.bot.dismiss -text "Dismiss" -command {destroy .addnew}   pack $w.bot.apply $w.bot.dismiss -side left -expand  1   PositionWindow $w}# The SetStatus procedure is used to set GUI status messages in the status window.# It's a general-purpose routine to display both error and informational messages.# If a type error occurs, then an error bitmap will be displayed in the status window.proc SetStatus {type text {timer 5000}} {   global statusText  statusImgWin   set statusText $text   after $timer "set statusText \"\""   $statusImgWin config -bitmap $type   after $timer "$statusImgWin config -bitmap \"\""}# The AddToView command will add a nick to the option button.# Before it adds the item to the option menu, it makes sure that the user had supplied# the required information.proc AddToView  {type command {nick ""}}  {   global tailOpts  viewOptMenu       catch {Stop}   if {$type == "file"} {      set nick $command      if {$command == ""} {          SetStatus error "Please supply File name..."               }   } elseif  {$type == "command"} {      if {($nick == "") || ($command == "") } {         SetStatus error "Please supply both nick and command names..."         return      }   }   set l [list  "$type" "$nick" "$command"]   if ![info exists tailOpts(wins)] {      set tailOpts $l      return   } else {      foreach item $tailOpts(wins) {         if {$nick == [lindex $item 1]} {            if {$type == "file"} {               SetStatus info "File $nick is all ready in the tail list...."                        } else {               SetStatus info "Nick $nick is all ready in the tail list...."            }            return;         }      }      lappend tailOpts(wins) $l   }   UpdateOptionMenu      $viewOptMenu invoke end}# The DeleteNicks routine will create a simple listbox-based user interface for the user to delete the nicks.proc DeleteNicks {} {   global   tailOpts   if ![info exists tailOpts(wins)] {      SetStatus info "No entries to delete..."      return;   }   if {$tailOpts(wins) == {}} {      SetStatus info "No entries to delete..."      return;   }    catch {destroy .delent}   toplevel .delent   set w .delent   wm title $w "Delete Entry"   scrollbar $w.h -orient horizontal -command "$w.list xview"   scrollbar $w.v -orient vertical -command "$w.list yview"   listbox $w.l -selectmode single -width 20 -height 10 \        -setgrid 1 -xscroll "$w.h set" -yscroll "$w.v set"    frame $w.buts     button $w.buts.d -text "Delete" -command {        set index [.delent.l curselection ];        if {$index == ""} {return}        set sel [.delent.l get $index ];         puts "sel $sel ; index $index"        DeleteFromView $sel;        .delent.l  delete $index    }    button $w.buts.dismiss -text "Dismiss" -command "destroy $w"        grid $w.l -row 0 -column 0 -columnspan 2 -sticky "news"    grid $w.v -row 0 -column 2 -sticky "ns"    grid $w.h -row 1 -column 0 -columnspan 2 -sticky "we"    grid $w.buts -row 2 -column 0 -columnspan 3    pack $w.buts.d $w.buts.dismiss -side left -padx 10   foreach ent $tailOpts(wins) {     $w.l insert end [lindex $ent 1]   }    PositionWindow $w}    # The DeleteFromView routine is an internal routine that removes the specified nick from the data structures# and updates the optionbutton.proc DeleteFromView {nick} {   global tailOpts    if {$nick == ""} {        return    }   set newList {}   if ![info exists tailOpts(wins)] {      return   }   foreach item $tailOpts(wins) {      if {$nick != [lindex $item 1]} {         lappend newList $item      }    }   set tailOpts(wins) $newList   UpdateOptionMenu}# The PositionWindow routine centers a toplevel dialogue box around its parent.# It is used to map dialog boxes on the main window, instead of some far-away corner of the screen.## PositionWindow  --#	#	Position the toplevel window centered to its parent.##  Arguments:#	toplevel window.#	#  Results:#	Positions the window #proc PositionWindow {w} {   set paren [winfo parent $w]   wm iconify $w   set parenConf [wm geometry $paren]   set parenConf [split $parenConf {+ - x}]   set winConf [split [wm geometry $w] {+ - x}]   set X [expr [lindex $parenConf 2] + [lindex $parenConf 0]/2 - \	      [winfo reqwidth $w]/2]   set Y [expr [lindex $parenConf 3] + [lindex $parenConf 1]/2 - \	      [winfo reqheigh $w]/2]   wm geometry $w +$X+$Y   wm deiconify $w}# The UpdateOptionMenu command updates the nicks option menu widget.#  UpdateOptionMenu --####  Arguments:###  Results:#proc UpdateOptionMenu {} {   global tailOpts curNick viewOptMenu   $viewOptMenu delete 0 end   if ![info exists tailOpts(wins)] {      return   }   if {$tailOpts(wins) == {}} {      set curNick ""      return   }   foreach item $tailOpts(wins) {       $viewOptMenu add command -label [lindex $item 1] -command "catch Stop; TailFile  \"[lindex $item 0]\" \"[lindex $item 2]\" \"[lindex $item 1]\" "      set curNick [lindex $item 1]   }}# Finally, we map the main window.wm withdraw .toplevel .tBuildTailGui .t

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -