icehawk
icehawk

Reputation: 1235

Error when trying to use puts in TCL/Expect

I have the following script:

#!/usr/bin/expect
set timeRegex "pengbumm"
expect {
   default { puts "nicht gefunden" }
   -re $timeRegex { puts "gefunden" }
}

If I execute it like this I get an error:

martin:/tmp$ echo "pengibumm" |./bla.exp
error writing "stdout": bad file number while executing
"puts "nicht gefunden" "
invoked from within
"expect {
     default { puts "nicht gefunden" }
     -re $timeRegex { puts "gefunden" }
 }"
 (file "./bla.exp" line 4)
 martin:/tmp$ echo "pengbumm" |./bla.exp
 gefunden
 martin:/tmp$

Why the heck does one puts work and the other doesn't? And how can I fix this?

I am guessing it has something to do with all the input being consumed, but that certainly should not stop puts from working.

Upvotes: 2

Views: 1624

Answers (2)

Paul Donohue
Paul Donohue

Reputation: 1171

It looks like expect assumes channel input/output pairs cannot be uni-directional, so expect_user closes both stdin and stdout after it receives EOF on stdin. While this makes sense for most spawned commands, it doesn't make sense for the current script's stdin/stdout.

In addition to pynexj's workaround (using puts stderr for output, since stderr isn't closed by expect_user when it receives EOF on stdin), it looks like you can use Tcl gets or read commands instead of expect_user to work around this:

set input [read stdin]
if [regexp {pengbumm} $input] then {
  puts "nicht gefunden"
} else {
  puts "gefunden"
}

Upvotes: 0

pynexj
pynexj

Reputation: 20688

Seems like expect closes stdout when it get EOF from stdin in this scenario:

$ echo | expect -c 'expect eof { puts eof }'
error writing "stdout": bad file number
    while executing
"puts eof "
    invoked from within
"expect eof { puts eof }"
$

Not sure if this is a bug but usually expect is not used this way without spawning a process.

UPDATE:

Just found a workaround. You can puts to stderr instead of stdout:

$ echo | expect -c 'expect eof { puts stderr eof }'
eof
$

Upvotes: 2

Related Questions