Reputation: 790
Right now I'm calling an external bash script via open, because said script might run for seconds or it might run for minutes. The only things that are certain are:
Reading and using the text outputted by the shell script does work. But I don't have a clue on how to read the return code.
The (simplified) TCL script looks like this:
#!/usr/bin/tclsh
proc run_script {} {
set script "./testing.sh"
set process [open "|${script}" "r"]
chan configure $process -blocking 0 -translation {"lf" "lf"} -encoding "iso8859-1"
while {[eof $process] == 0} {
if {[gets $process zeile] != -1} {
puts $zeile
}
update
}
close $process
return "???"
}
set rc [run_script]
puts "RC = ${rc}"
The (simplified) shell script does look like this:
#!/bin/bash
echo Here
sleep 1
echo be
sleep 2
echo dragons
sleep 4
echo ....
sleep 8
exit 20
So how do I read the return code of the shell script via tcl?
Upvotes: 5
Views: 1292
Reputation: 4813
You need to switch the file descriptor back to blocking before you close it to get the exit code. For example:
You can use try ... trap
, which was implemented with tcl 8.6:
chan configure $process -blocking 1
try {
close $process
# No error
return 0
} trap CHILDSTATUS {result options} {
return [lindex [dict get $options -errorcode] 2]
}
An other option would be to use catch
:
chan configure $process -blocking 1
if {[catch {close $process} result options]} {
if {[lindex [dict get $options -errorcode] 0] eq "CHILDSTATUS"} {
return [lindex [dict get $options -errorcode] 2]
} else {
# Rethrow other errors
return -options [dict incr options -level] $result
}
}
return 0
Upvotes: 4
Reputation: 137587
To get the status in 8.5, use this:
fconfigure $process -blocking 1
if {[catch {close $process} result options] == 1} {
set code [dict get $options -errorcode]
if {[lindex $code 0] eq "CHILDSTATUS"} {
return [lindex $code 2]
}
# handle other types of failure here...
}
To get the status in 8.4, use this:
fconfigure $process -blocking 1
if {[catch {close $process}] == 1} {
set code $::errorCode
if {[lindex $code 0] eq "CHILDSTATUS"} {
return [lindex $code 2]
}
# handle other types of failure here...
}
Upvotes: 3