Shell pipes break readline completion
Seemingly at random I found myself without readline
in my terminal,
just for it to restart working later on. This seemed to happen especially when
trying to use pdb
after setting a Python breakpoint()
.
I originally thought about my TERM
variables being misconfigured, the use of
direnv
, and so on. But it was none of that. On a closer look, it only
happened when running make extract
to process Beancount transactions from
bank statements and financial documents. Why?
The Makefile extract
target looks as follows:
extract:
$(RUN) bean-extract -f $(INDEX).beancount -e $(INDEX).beancount $(INDEX).import "$(EXPANDED_TARGET)" | tee /tmp/extracted.beancount
It calls bean-extract
and then pipes the result to a file. When this would
fail (under the hood, it calls a bunch of Python script that parse the
different documents), Iβd throw a breakpoint()
, get into pdb
and be annoyed
by the lack of completion.
Other times, Iβd run the command directly β and readline completion would work, deepening the mystery.
It then dawned on me and in retrospect it is obvious; I should have noticed
earlier. Well-behaved Unix processes will detect that their standard input is
not a terminal and disable shell completion (often implemented through GNU
readline
).
For CPython, I think the relevant code is here. Entering text into a terminal is indeed complicated.
Mystery solved! Below you can see the behavior in action (youβll need Javascript enabled, or you can see it here):