'How to login to bash with current user, and the user's .bashrc file, in jupyterlab?

I have a configuration file setup in .bashrc which I would like to apply to all terminals opened automatically in my jupyterlab.

Currently jupyterlab terminals start like this, without any of the configuration in my .bashrc file.

jupyterlab terminal

If I simply type bash and hit enter it does exactly what I want. Like below.

terminal after typing bash

I would like for it to automatically open like this.

How can this be achieved?

Here is a very similar question.

But none of the solutions work, I mean it does open bash, not shell, so I'm not sure if that solution is what I'm looking for. But I've changed my tornado settings, I've added the environment variable SHELL=/bin/bash but none of it has any affect. (I've obviously restarted jupyterhub each time to see the effect.

Here is my jupyterhub start file 'jupyterhub.service', located in '/etc/systemd/'.

[Unit]
Description=Jupyterhub
After=syslog.target network.target
[Service]
User=root
Type=simple
Environment="PATH=/anaconda3/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
Environment="SPARK_HOME=/spark-2.3.2-bin-hadoop2.7/"
Environment="SHELL=/bin/bash"
ExecStart=/anaconda3/bin/jupyterhub -f /etc/jupyter/jupyterhub_config.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target


Solution 1:[1]

I have the very same problem when configuring JupyterLab (similar to JupyterHub) as a Systemd-Service.

First Solution

(Please first try the second solution.) We can address the problem by change the default configuration in jupyter_notebook_config.py (as one of the comment and answer said, but the conclusion/solution is just the reverse.)

The related comment: enter image description here

The file jupyter_notebook_config.py is located at $HOME/.jupyter/. If it does not exist, it can be generated by running:

jupyter lab --generate-config  

After this file is located, we modify the content as follows:

# This is for Jupyter Notebook
# c.NotebookApp.terminado_settings = {'shell_command': ['/bin/bash']}
# This is for JupyterLab/JupyterHub
c.ServerApp.terminado_settings = {'shell_command': ['/bin/bash']}

Notably, the options '--login', '-i' mentioned in above comment and answer prevent the terminal loading .bashrc. Without these options, the shell looks like (which is expected):

(base) [ml@soc3 /]$ python --version
Python 3.9.5

While with these options, the shell looks like (not initilized with .bashrc):

bash-4.2$ python --version
Python 2.7.5

Second Solution

create or edit the ~/.bash_profile file to automaitically load ~/.bashrc:

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

After reading more about login and interactive shell, I found that the default behavior of Jupyter's terminal is login and interactive, and it will source the ~/.bash_profile if the file exists (usually, it will load the ~/.bashrc file). My problem is that I created a new user for running JupyterLab, while the default ~/.bash_profile is not created for this user, and hence ~/.bashrc will not be sourced. Furthermore, I have previously run JupyerLab with root user, which has the mentioned configuration files, thus the JupyerLab terminal works well.

I think it is more sounded. Though the first solution works, why it works is not clear to me.

Solution 2:[2]

You could try creating a file

$HOME/.bash_login

and source .bashrc from there

source $HOME/.bashrc

and see if it does what you wanted.

Solution 3:[3]

Based on this github issue, bashrc needs to be sourced from profile.

I've confirmed this works by adding the following to /home/jovyan/.profile:

bash
source /home/jovyan/.bashrc

Solution 4:[4]

Let me do some wild guess for what happened:

1. Config issue

As one of the comment said, change jupyter_notebook_config.py to include

c.NotebookApp.terminado_settings = {'shell_command': ['/bin/bash', '--login', '-i']}

The shell_command should be an array of three strings. See https://github.com/jupyterlab/jupyterlab/issues/4042

2. Your id or your shell

Check these right after you launch the terminal

$ whoami
$ echo $SHELL

to see you have the right user and right shell. If your user is not right, it is expecting the .bashrc in a different user's home directory. If your shell is not right, e.g., /bin/sh instead of /bin/bash (which in fact are often hard-link of each other), it will not read .bashrc

If so, try to see if your $SHELL env variable as seen by Jupyter is correct. Jupyter should use that if you didn't specify shell_command as above

3. Jupyter may be giving you a non-interactive shell

If your bash really doesn't read your .bashrc, it may be invoked as non-interactive shell (I don't know how). To check you can try run this:

$ ls
$ !!

The first ls command can be any command. The second !! is to use bash's history expansion to recall the last executed command. If will not substitute if it is not an interactive shell.

I don't expect that and I don't know how to fix if this happens.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jetchisel
Solution 3 neurochief
Solution 4 adrtam