tclexpect

Is it possible to force `expect` to `puts` a string of nulls without a newline?


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?


Solution

  • 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.