This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

[SOLVED] Cannot run bgexec in an if statement

Help for those learning Tcl or writing their own scripts.
Post Reply
E
EzMe
Voice
Posts: 5
Joined: Tue Jan 15, 2013 5:50 am

[SOLVED] Cannot run bgexec in an if statement

Post by EzMe »

Hi all,

I've been using eggdrop for some years now and decided to make my own tcl script now. What I'm trying to do is start an external bash script, wait for it's output and echo a line containing certain info into the chan. I've got this working and the code looks like this:

Code: Select all

bind pub - !start start_msg
proc start_msg {nick uhost hand chan arg} {
bgexec "./go.sh" callback 5
}
proc callback {input} {
 foreach line [split $input "\n"] {
      if  [string match "*hex:*" [string tolower $line]] {
      puthelp "privmsg #mychan : Results : $line"
           }
      }
}
As you can see I'm using another tcl called bgexec.tcl in order to make this work.

Now, sinds this is working I want to add an syntax to this program in go.sh true IRC. This syntaxt needs to meet a couple of requirements in order to be valid. My code looks like this:

Code: Select all

bind pub * !start pub_go
proc pub_go { nick host handle chan text} {
	set arg $text
	        if {![file exists syntax.txt]} {set a [open syntax.txt w]; close $a}
        set syntax [open syntax.txt r+]
                if {$arg == "" && [read $syntax] != ""} {
                putmsg $chan "\002\0034::\003 Program started...\002"
                puts $syntax $arg
                close $syntax
# ------------------------------------------------------------------
# Code downhere does not start
                bgexec "./go.sh" callback 5
                proc callback {input} {
                foreach line [split $input "\n"] {
                      if  [string match "*hex:*" [string tolower $line]] {
                      puthelp "privmsg #mychan : Results : $line"
                           }
                     }
                 }
# Till here
# ------------------------------------------------------------------
        } elseif {$arg == "" && [read $syntax ] == ""} {
                close $syntax 
                putmsg $chan "\002\0034::\003 Add a syntax to program first\002"
        } elseif {[lsearch -inline $arg *:*:*:*:::] == $arg} {
                close $syntax 
                putmsg $chan "\002\0034::\003 Program started with syntax: $arg\002"
                if {[file exists syntax.txt]} {file delete -force syntax.txt}
                set b [open syntax.txt a]
                puts $b $arg
                close $b
# ------------------------------------------------------------------
# Code downhere does not start
                bgexec "./go.sh" callback 5
                proc callback {input} {
                foreach line [split $input "\n"] {
                      if  [string match "*hex:*" [string tolower $line]] {
                      puthelp "privmsg #mychan : Results : $line"
                           }
                      }
                }
# Till here
------------------------------------------------------------------
          else {
                close $syntax
                putmsg $chan "\002\0034::\003 Invalid syntax\002"
        }
   }
}
So my question is, how can I start bgexec after it meets all the requirements? Is there a way to proc it?

Thanks in advanced!

Grtz EzMe :)


btw, bgexec.tcl looks like this:

Code: Select all

##
#
# bgexec.tcl v1.1 - by strikelight ([sL] @ EFNet) (09/05/02)
#
# For eggdrop1.1.5-eggdrop1.6.x
#
# Contact:
# - E-Mail: strikelight@tclscript.com
# - WWW   : http://www.TCLScript.com
# - IRC   : #Scripting @ EFNet
#
##
#
# Description:
#
# This script is for other scripters to use as a replacement
# for the "exec" command so that they may execute commands to
# the system in the background. (non-blocking mode)
#
##
#
# History:
#
# (09/05/02):v1.1 - Fixed callback bug to allow calling of a callback
#                   procedure with a list of parameters
#                   (ie. bgexec <command> [list <command_callback> <arg1> <arg2>])
#
# (05/27/02):v1.0 - Initial Release
#
##
#
# Usage:
#
# example #1 (for eggdrop1.4.x-eggdrop1.6.x users):
#
#   proc callback {input} {
#     foreach line [split $input "\n"] {
#       putserv "PRIVMSG #test :$line"
#     }
#   }
#   bgexec "command here" callback
#
# NOTE: This example (#1) will also work for eggdrop1.1.5-1.3.x users,
#       however, it will only be non-blocking for a default of 5 seconds
#       (since egg1.1.5-egg1.3.x do not use Tcl_DoOneEvent, a vwait will
#        be executed after 5 seconds, thus blocking processing until
#        the execution of the command is done). See example #2 for changing
#       the default waiting time.
#
#
# example #2 (for eggdrop1.1.5-eggdrop1.3.x users):
#
#   proc callback {input} {
#     foreach line [split $input "\n"] {
#       putserv "PRIVMSG #test :$line"
#     }
#   }
#   bgexec "command here" callback 20 ;# this will wait 20 seconds before
#                                      # checking for the results of the
#                                      # command (and effectively, returning
#                                      # to blocking mode). Change 20 to
#                                      # whatever you feel comfortable with.
#
#
#
# example #3 (error checking):
#
#   proc callback {input} {
#     ...
#   }
#   if {[catch {bgexec "command here" callback} err]} {
#     putlog "Error executing command: $err"
#   }
#
#
# example #4 (multi-parameters):
#
#   proc callback {arg1 arg2 input} {
#     ...
#   }
#   if {[catch {bgexec "command here" [list callback $arg1 $arg2]} err]} {
#     putlog "Error executing command: $err"
#   }
#
##

set bgexec(version) "1.1"

proc bgexec_process {fileid callback} {
  global buffer bgexectest
  if {[eof $fileid]} {
    catch {close $fileid}
    set buffer($fileid) [lrange $buffer($fileid) 0 [expr [llength $buffer($fileid)] - 2]]
    set buffer($fileid) [join $buffer($fileid) "\n"]
    catch {eval $callback {$buffer($fileid)}}
    catch {unset buffer($fileid)}
    set bgexectest($fileid) 1
    return
  }
  if {[catch {gets $fileid dataline} err]} {
    catch {close $fileid}
    set buffer($fileid) "error: $err"
    catch {eval $callback {$buffer($fileid)}}
    catch {unset buffer($fileid)}
    set bgexectest($fileid) 1
  }
  lappend buffer($fileid) $dataline
}

proc bgexec {{command ""} {callback ""} {flush 5}} {
  global buffer bgeggversion
  if {($command == "") || ($callback == "")} {
    return -code error "wrong # args: should be \"bgexec command callback ?wait?\""
  }
  if {[catch {info body [lindex [split $callback] 0]} err]} {
    return -code error "$err"
  }
  if {[catch {set infile [open "|$command" "r+"]} err]} {
    return -code error "$err"
  }
  set buffer($infile) ""
  fileevent $infile readable [list bgexec_process $infile $callback]
  fconfigure $infile -blocking 0
  if {[info exists bgeggversion] && ($bgeggversion < 1040000)} {
    utimer $flush "bgexec_flush $infile"
  }
  return $infile
}

if {[info exists version]} {
  set bgeggversion [string trimleft [lindex $version 1] 0]
  if {$bgeggversion < 1040000} {
    proc bgexec_flush {fileid} {
      global bgexectest
      vwait bgexectest($fileid)
      catch {unset bgexectest($fileid)}
    }
  }
}

putlog "bgexec.tcl v$bgexec(version) by strikelight now loaded."

Last edited by EzMe on Tue Jan 15, 2013 9:08 am, edited 1 time in total.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Have you tried moving the callback proc outside the pub_go proc?
Once the game is over, the king and the pawn go back in the same box.
E
EzMe
Voice
Posts: 5
Joined: Tue Jan 15, 2013 5:50 am

Post by EzMe »

Thanks caesar! That did the trick! You just made my day :)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Your welcome. Anyway, you should rethink your pub_go proc code as it's a bit messy, I tried to follow your logic but failed miserably (tiered I guess).
Once the game is over, the king and the pawn go back in the same box.
E
EzMe
Voice
Posts: 5
Joined: Tue Jan 15, 2013 5:50 am

Post by EzMe »

Hahaha cheers m8 :) It seems it is working fine all and, as this is my first script, I'm pretty satisfied with this :)
Post Reply