Consider the following script, which I'll call PrintNull.tcl
.
puts -nonewline "\0\0\0\0"
If I run this script with tclsh
, it outputs the four null characters as expected:
tclsh PrintNull.tcl | xxd
00000000: 0000 0000
If I run this script with expect
, it outputs nothing:
expect -f PrintNull.tcl | xxd
# No output at all
Curiously, if I modify the script slightly and remove the -nonewline
, both tclsh
and expect
behave the same way, but now they both have an extra newline character:
expect -f PrintNull.tcl | xxd
00000000: 0000 0000 0a .....
tclsh PrintNull.tcl | xxd
00000000: 0000 0000 0a .....
What is causing this behavior, and is it possible to force expect to behave like tcl when processing puts
?
Explicitly flushing stdout can solve the issue:
$ expect -c 'puts -nonewline "\0\0\0\0" ' | xxd
$ expect -c 'puts -nonewline "\0\0\0\0"; flush stdout' | xxd
00000000: 0000 0000 ....
Based on the observation stdout is line-buffered for both Tcl and Expect but seems like Expect does not flush stdout before exiting.
NOTE: The issue is not specific for NULL chars. For example expect -c 'puts -nonewline foobar'
can also reproduce the issue.