I wanted to use the `unbuffer' command from `expect' package. `unbuffer' can be used to run another command in a way it sees its STDOUT as a terminal.
Even the simplest invokation
guix shell expect -- unbuffer echo test
freezes without printing "test" as it should.
I found that the initial lines in all `expect's executable script files
contain an extra `exec sh' line that causes the script to enter an
endless recursion when interpreted by a POSIX shell.
--8<---------------cut here---------------start------------->8---
$ head -6 $(file $(guix build expect)/bin/* | grep text | sed
's/^\([^:]\+\).*/\1/')
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/autoexpect <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/autopasswd <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/cryptdir <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/decryptdir <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/dislocate <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/ftp-rfc <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/kibitz <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/lpunlock <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/mkpasswd <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/multixterm <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/passmass <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/rftp <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/rlogin-cwd <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/timed-read <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/timed-run <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/tknewsbiff <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/tkpasswd <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/unbuffer <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/weather <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/xkibitz <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
==> /gnu/store/bwix93j3pysx464sh4mp98lsjgsbpcri-expect-5.45.4/bin/xpstat <==
#!/gnu/store/m0xdsa8cfq6mq1kxgxmpmpg71la4f0b9-bash-minimal-5.1.16/bin/sh
# \
exec sh "$0" ${1+"$@"}
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
--8<---------------cut here---------------end--------------->8---
An artifact of incorrect shebang patching, perhaps? Nonetheless, as
one might guess, giving the script directly to tclsh makes it work:
--8<---------------cut here---------------start------------->8---
$ guix shell tcl expect bash -- bash -c 'tclsh $(which unbuffer) echo test'
test
--8<---------------cut here---------------end--------------->8---
I am using `expect' from Guix d3d157bc61c4a6a3fac11e33d26f6f2a72a24151
from May 21, 2025.
Best!
--
W. Kosior
website: https://koszko.org/koszko.html
fediverse: https://friendica.me/profile/koszko/profile
PGP fingerprint: E972 7060 E3C5 637C 8A4F 4B42 4BC5 221C 5A79 FD1A
pgpXSbOgWr_GV.pgp
Description: OpenPGP digital signature
