#todo - investigate cause of punk86 run hanging sometimes. An 'after 500' before exit in the called script fixes the issue. punk87 doesn't seem to be affected.
lappend PUNKARGS [list {
@id -id ::shellrun::run
@cmd -name "shellrun::run"\
-summary "Run an external command, streaming stdout/stderr to the console in real-time"\
-help\
"Run an external command and return the shellfilter exitinfo dict.
stdout and stderr are written to the console as they arrive;
nothing is captured for the return value. The exitcode is
part of the returned dict — a non-zero exitcode is NOT raised
as a Tcl error, the caller must check it explicitly.
Use -tcl to run a Tcl script/command instead of an external
process; in that case the returned dict carries a 'result'
key (or error/errorCode/errorInfo on failure) instead of an
exitcode."
@leaders -min 0 -max 0
@opts
-nonewline -type none
-tcl -type none -default 0
-debug -type none -default 0
--timeout= -type integer
-nonewline -type none -help\
"Accepted for compatibility with runout/runerr/runx. Has no
effect on run because run does not capture or return stdout."
-tcl -type none -default 0 -help\
"Interpret cmdname (and cmdarg) as a Tcl command/script rather
than an external process."
-debug -type none -default 0 -help\
"Enable debug diagnostics from shellfilter::run."
--timeout= -type integer -help\
"Timeout in milliseconds for the external process."
@values -min 1 -max -1
cmdname -type string
cmdarg -type any -multiple 1 -optional 1
cmdname -type string -help\
"Name of the external command (or Tcl command when -tcl is
given)."
cmdarg -type any -multiple 1 -optional 1 -help\
"Additional arguments passed through to the command."
}]
proc run {args} {
#set_last_run_display [list]
#set splitargs [get_run_opts $args]
#set runopts [dict get $splitargs runopts]
#set runoptslong [dict get $splitargs runoptslong]
#set cmdargs [dict get $splitargs cmdargs]
set argd [punk::args::parse $args withid ::shellrun::run]
lassign [dict values $argd] leaders opts values received
@ -206,11 +175,25 @@ namespace eval shellrun {
lappend PUNKARGS [list {
@id -id ::shellrun::runconsole
@cmd -name "shellrun::runconsole"\
-summary "Run a command via exec with stdout/stderr directed to the console, mimicking Tcl's unknown handler"\
-help\
"Resolve cmdname via auto_execok and exec it with stdout
and stderr redirected to the active console. The result is
returned via uplevel with the exec result/options dict,
mirroring the way Tcl's unknown proc handles external
commands.
Unlike run, this uses exec semantics — there is no
exitcode in the return value and stdout/stderr are not
captured separately."
@leaders -min 0 -max 0
@opts
@values -min 1 -max -1
cmdname -type string
cmdarg -type any -multiple 1 -optional 1
cmdname -type string -help\
"Name of the command to resolve via auto_execok and run."
cmdarg -type any -multiple 1 -optional 1 -help\
"Additional arguments passed to the resolved command."
}]
#run in the way tcl unknown does - but without regard to auto_noexec
proc runconsole {args} {
@ -256,16 +239,42 @@ namespace eval shellrun {
}
lappend PUNKARGS [list {
@id -id ::shellrun::runout
@cmd -name "shellrun::runout"\
-summary "Run an external command and return its stdout"\
-help\
"Run an external command, capture stdout and stderr, and
return stdout as the result. stderr and the exitcode are
emitted via repl telemetry chunks but are not part of the
return value.
By default no console output is produced while the command
runs; use -echo to tee stdout and stderr to the console in
real-time. Use -nonewline to strip a trailing newline from
the returned stdout.
Use -tcl to run a Tcl script/command instead of an external
process."
@leaders -min 0 -max 0
@opts
-echo -type none
-nonewline -type none
-tcl -type none -default 0
-debug -type none -default 0
--timeout= -type integer
-echo -type none -help\
"Tee stdout and stderr to the console in real-time while still
capturing them for the return value."
-nonewline -type none -help\
"Strip a trailing newline (\\r\\n or \\n) from the returned
stdout."
-tcl -type none -default 0 -help\
"Interpret cmdname (and cmdarg) as a Tcl command/script rather
than an external process."
-debug -type none -default 0 -help\
"Enable debug diagnostics from shellfilter::run."
--timeout= -type integer -help\
"Timeout in milliseconds for the external process."
@values -min 1 -max -1
cmdname -type string
cmdarg -type any -multiple 1 -optional 1
cmdname -type string -help\
"Name of the external command (or Tcl command when -tcl is
given)."
cmdarg -type any -multiple 1 -optional 1 -help\
"Additional arguments passed through to the command."
}]
proc runout {args} {
set argd [punk::args::parse $args withid ::shellrun::runout]
@ -284,11 +293,6 @@ namespace eval shellrun {
set runerr ""
set RST [a]
#set splitargs [get_run_opts $args]
#set runopts [dict get $splitargs runopts]
#set cmdargs [dict get $splitargs cmdargs]
#puts stdout "RUNOUT cmdargs: $cmdargs"
#todo add -data boolean and -data lastwrite to -settings with default being -data all
@ -422,16 +426,42 @@ namespace eval shellrun {
lappend PUNKARGS [list {
@id -id ::shellrun::runerr
@cmd -name "shellrun::runerr"\
-summary "Run an external command and return its stderr"\
-help\
"Run an external command, capture stdout and stderr, and
return stderr as the result. stdout and the exitcode are
emitted via repl telemetry chunks but are not part of the
return value.
By default no console output is produced while the command
runs; use -echo to tee stdout and stderr to the console in
real-time. Use -nonewline to strip a trailing newline from
the returned stderr.
Use -tcl to run a Tcl script/command instead of an external
process."
@leaders -min 0 -max 0
@opts
-echo -type none
-nonewline -type none
-tcl -type none -default 0
-debug -type none -default 0
--timeout= -type integer
-echo -type none -help\
"Tee stdout and stderr to the console in real-time while still
capturing them for the return value."
-nonewline -type none -help\
"Strip a trailing newline (\\r\\n or \\n) from the returned
stderr."
-tcl -type none -default 0 -help\
"Interpret cmdname (and cmdarg) as a Tcl command/script rather
than an external process."
-debug -type none -default 0 -help\
"Enable debug diagnostics from shellfilter::run."
--timeout= -type integer -help\
"Timeout in milliseconds for the external process."
@values -min 1 -max -1
cmdname -type string
cmdarg -type any -multiple 1 -optional 1
cmdname -type string -help\
"Name of the external command (or Tcl command when -tcl is
given)."
cmdarg -type any -multiple 1 -optional 1 -help\
"Additional arguments passed through to the command."
}]
proc runerr {args} {
set argd [punk::args::parse $args withid ::shellrun::runerr]
@ -449,10 +479,6 @@ namespace eval shellrun {
set runout ""
set runerr ""
#set splitargs [get_run_opts $args]
#set runopts [dict get $splitargs runopts]
#set cmdargs [dict get $splitargs cmdargs]
set callopts [dict create]
if {[dict exists $received "-tcl"]} {
dict set callopts -tclscript 1
@ -567,6 +593,43 @@ namespace eval shellrun {
}
lappend PUNKARGS [list {
@id -id ::shellrun::runx
@cmd -name "shellrun::runx"\
-summary "Run an external command and return a dict of stdout, stderr, and exitcode"\
-help\
"Run an external command, capture stdout and stderr, and
return a dict containing stdout, stderr, and exitcode (or
result/error/errorCode/errorInfo for -tcl calls).
No console output is produced unless -echo is given. Use
-nonewline to strip trailing newlines from captured stdout
and stderr before returning.
Use -tcl to run a Tcl script/command instead of an external
process."
@leaders -min 0 -max 0
@opts
-echo -type none -help\
"Tee stdout and stderr to the console in real-time while still
capturing them for the return dict."
-nonewline -type none -help\
"Strip a trailing newline (\\r\\n or \\n) from captured stdout
and stderr in the returned dict."
-tcl -type none -default 0 -help\
"Interpret cmdname (and cmdarg) as a Tcl command/script rather
than an external process."
-debug -type none -default 0 -help\
"Enable debug diagnostics from shellfilter::run."
--timeout= -type integer -help\
"Timeout in milliseconds for the external process."
@values -min 1 -max -1
cmdname -type string -help\
"Name of the external command (or Tcl command when -tcl is
given)."
cmdarg -type any -multiple 1 -optional 1 -help\
"Additional arguments passed through to the command."
}]
proc runx {args} {
#set_last_run_display [list]
variable runout
@ -574,11 +637,10 @@ namespace eval shellrun {
set runout ""
set runerr ""
set splitargs [get_run_opts $args]
set runopts [dict get $splitargs runopts]
set cmdargs [dict get $splitargs cmdargs]
set argd [punk::args::parse $args withid ::shellrun::runx]
lassign [dict values $argd] leaders opts values received