diff --git a/notebook/notebookapp.py b/notebook/notebookapp.py index 57833caec0..0bc3c8adbd 100755 --- a/notebook/notebookapp.py +++ b/notebook/notebookapp.py @@ -1160,7 +1160,10 @@ def _update_webapp_settings(self, change): """) ) terminado_settings = Dict(config=True, - help=_('Supply overrides for terminado. Currently only supports "shell_command".')) + help=_('Supply overrides for terminado. Currently only supports "shell_command". ' + 'On Unix, if "shell_command" is not provided, a non-login shell is launched ' + "by default when the notebook server is connected to a terminal, a login " + "shell otherwise.")) cookie_options = Dict(config=True, help=_("Extra keyword arguments to pass to `set_secure_cookie`." diff --git a/notebook/terminal/__init__.py b/notebook/terminal/__init__.py index 2d216cc1e6..00cb7b0fbe 100644 --- a/notebook/terminal/__init__.py +++ b/notebook/terminal/__init__.py @@ -1,4 +1,5 @@ import os +import sys import terminado from ..utils import check_version @@ -18,16 +19,18 @@ def initialize(nb_app): default_shell = 'powershell.exe' else: default_shell = which('sh') - shell = nb_app.terminado_settings.get('shell_command', - [os.environ.get('SHELL') or default_shell] - ) - # Enable login mode - to automatically source the /etc/profile - # script, but only for non-nested shells; for nested shells, it's - # superfluous and may even be harmful (e.g. on macOS, where login - # shells invoke /usr/libexec/path_helper to add entries from - # /etc/paths{,.d} to the PATH, reordering it in the process and - # potentially overriding virtualenvs and other PATH modifications) - if os.name != 'nt' and int(os.environ.get("SHLVL", 0)) < 1: + shell_override = nb_app.terminado_settings.get('shell_command') + shell = ( + [os.environ.get('SHELL') or default_shell] + if shell_override is None + else shell_override + ) + # When the notebook server is not running in a terminal (e.g. when + # it's launched by a JupyterHub spawner), it's likely that the user + # environment hasn't been fully set up. In that case, run a login + # shell to automatically source /etc/profile and the like, unless + # the user has specifically set a preferred shell command. + if os.name != 'nt' and shell_override is None and not sys.stdout.isatty(): shell.append('-l') terminal_manager = nb_app.web_app.settings['terminal_manager'] = TerminalManager( shell_command=shell,