bash_kernel icon indicating copy to clipboard operation
bash_kernel copied to clipboard

"stty sane" setting causes Bash kernel to misbehave

Open thomasjm opened this issue 7 years ago • 5 comments

This is a weird one. It seems if you put stty sane in your .bashrc file, then the Bash kernel will misbehave. Misbehavior includes

  1. Echoing every input line back along with the output
  2. Autocomplete contains items it shouldn't: for example, if you type slee and press tab it should autocomplete to sleep, but instead it suggests both slee and sleep.
  3. Commands come back with an exit code of 1 (I think)

Here's a repro based on Docker:

  1. mkdir bash-kernel-debug && cd bash-kernel-debug
  2. Paste the following into a Dockerfile in this folder:
FROM ubuntu:18.04

USER root

# Add a user
RUN adduser user --home /home/user --disabled-password --gecos ""

# Install utilities
RUN apt-get update
RUN apt-get install -y python
RUN apt-get install -y locales
RUN apt-get install -y libzmq5-dev
RUN apt-get install -y wget

# Set the locale
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

# Install kernel: Python
RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py
RUN apt-get install -y python-dev
RUN apt-get install -y pkg-config
RUN pip install jupyter

# Install kernel: bash
RUN apt-get install -y python3-pip
RUN pip3 install jupyter
RUN pip3 install bash_kernel
RUN python3 -m bash_kernel.install

USER user

# Note: the presence of this line causes weird problems for bash_kernel
RUN echo "\n\nstty sane" >> /home/user/.bashrc

WORKDIR /home/user
  1. Build the container: docker build -t bash-kernel-debug .
  2. Run the container: docker run -it --rm bash-kernel-debug bash
  3. Inside the container, start a kernel: jupyter console --kernel bash
  4. Type a command like whoami and observe how the input echoes back.
  5. If you remove the stty sane line from the Dockerfile and re-build, the problem goes away.

Actually, an even easier repro if you already have a working Bash kernel installation is to simply type stty sane into a console or notebook. Then every subsequent command will misbehave the same way. I'll leave the Dockerfile above in case it's helpful though.


I found online that stty sane is equivalent to a complicated command for normalizing the treatment of special characters: stty cread -ignbrk brkint -inlcr -igncr icrnl -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke. But I have no idea why it causes issues. Hope this helps!

thomasjm avatar Jul 29 '18 03:07 thomasjm

bash_kernel works by running bash in a virtual terminal and scraping characters from it. It changes some of the terminal settings to achieve that. If you reset them from bash, stuff breaks. I don't know of any easy way around that.

takluyver avatar Aug 01 '18 09:08 takluyver

Got it. That happens in the replwrap library, right? It would be interesting to see which settings are changed.

In general I'm fine with avoiding stty sane, but it would be nice to handle it more gracefully. I think putting stty sane into the .bashrc is not an uncommon thing based on the number of tutorials I've seen recommending this command to fix terminal issues. And it caused enormous confusion with bash_kernel until I tracked it down.

Perhaps bash_kernel could apply its changes after bash has started up and evaluated .bashrc etc.? That would be a little more robust to config issues.

thomasjm avatar Aug 01 '18 10:08 thomasjm

Yep, that's pexpect.replwrap. IIRC, it disables echo and changes the prompt to something odd so you're unlikely to see the prompt in other output.

If it's coming from bashrc, it might be possible to do something about it. Have a look at the custom bashrc file that pexpect runs: https://github.com/pexpect/pexpect/blob/master/pexpect/bashrc.sh

takluyver avatar Aug 01 '18 10:08 takluyver

Ah, I didn't know that pexpect is manually sourcing .bashrc. So maybe it would be straightforward to run this script before the terminal changes are applied like I mentioned above.

Alternatively, perhaps bash_kernel could check that the terminal is in a good state before evaluating every code block?

I'm not sure how pressing this is for other users; things work fine for me now that I understand the problem. So I'll leave it to you what to do about it (if anything)--thanks!

thomasjm avatar Aug 03 '18 02:08 thomasjm

Truth be told, I'm unlikely to get to doing anything about it - it's not a problem for me personally, and there are plenty of other things to do. I'll leave the issue open in case anyone else wants to explore possible changes in this area.

takluyver avatar Aug 03 '18 18:08 takluyver