Alright, so what I've figured out is:
- If you background a process in a shell script, it sets stdin to /dev/null.
Which makes sense; it's just not something I ever thought about. So
that explains why stdin for script was set to /dev/null.
- The real problem isn't the tight loop for script(1); it's that when
this version of script gets an EOF on the "user" side (because the input
is set to /dev/null) it never writes an EOF to the other side, and
it ends waiting forever on the slave side for input to acknowledge the
welcome message. This was fixed relatively late in the script(1) for
MacOS X (really, in FreeBSD), and I see the Linux version says:
* The script(1) is usually faster than shell, so it's a good idea to wait until
* the previous message has been already read by shell from slave before we
* write to master. This is necessary especially for EOF situation when we can
* send EOF to master before shell is fully initialized, to workaround this
* problem we wait until slave is empty. For example:
* echo "date" | script
* Unfortunately, the child (usually shell) can ignore stdin at all, so we
* don't wait forever to avoid dead locks...
* Note that script is primarily designed for interactive sessions as it
* maintains master+slave tty stuff within the session. Use pipe to write to
* script(1) and assume non-interactive (tee-like) behavior is NOT well
The last paragraph is the key.
I'm not sure what to do here. This usage of script(1) seems a bit fragile.
I'd be willing to write a test to skip this test if script(1) doesn't work
right, but I'm not sure how easy that would be.
It occurs to me that since POSIX has standardized pseudo-tty functions, we
could write our own program to run stuff under a pty. That program would
not be very big. Other suggestions are welcome.
Nmh-workers mailing list