Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colorize terminal through /etc/bash.bashrc as /home/jovyan/.bashrc tends to be wiped #815

Open
consideRatio opened this issue Feb 20, 2019 · 8 comments
Labels
type:Enhancement A proposed enhancement to the docker images

Comments

@consideRatio
Copy link
Collaborator

consideRatio commented Feb 20, 2019

It is my understand that if we would not override /home/jovyan we probably would end up with a default .bashrc copied from /etc/skel/.bashrc, but that this is wiped in general due to mounting of storage in /home/jovyan.

Perhaps we could try to retain it somehow, for example by doing...

# Add systemwide .bashrc configuration additions that are normally found in /home/jovyan/.bashrc
USER root
RUN cat /etc/skel/.bashrc >> /etc/bash.bashrc
USER $NB_UID

Resulting changes from unmodified /etc/skel/.bashrc usage

  1. (not true, it requires force_color_prompt=yes is un-commented!) We get colors on the prompt, like...

image

  1. We get colors on the ls commands output

  2. (untested) We get a custom title that isn't Terminal 1 Terminal 2 etc on the terminal tabs, but instead the username and hostname and the path following that... It comes from the following section of the .bashrc and the first part of the PS1 variable. It is too messy though...

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

Resulting changes from modifying the /etc/skel/.bashrc before using

Assuming we do the following on the /etc/skel/.bashrc before we utilize it by for example augmenting /etc/bash.bashrc, we end up with a result that I consider pleasing.

  • remove /h from PS1
  • remove "\u@\h: " from the xterm title section
  • remove comment from force_color_prompt=yes

beautify-terminal


/etc/skel/.bashrc from Ubuntu 18.04

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
	# We have color support; assume it's compliant with Ecma-48
	# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
	# a case would tend to support setf rather than setaf.)
	color_prompt=yes
    else
	color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

/etc/bash.bashrc from Ubuntu 18.04

# System-wide .bashrc file for interactive bash(1) shells.

# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
# but only if not SUDOing and have SUDO_PS1 set; then assume smart user.
if ! [ -n "${SUDO_USER}" -a -n "${SUDO_PS1}" ]; then
  PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

# Commented out, don't overwrite xterm -T "title" -n "icontitle" by default.
# If this is an xterm set the title to user@host:dir
#case "$TERM" in
#xterm*|rxvt*)
#    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
#    ;;
#*)
#    ;;
#esac

# enable bash completion in interactive shells
#if ! shopt -oq posix; then
#  if [ -f /usr/share/bash-completion/bash_completion ]; then
#    . /usr/share/bash-completion/bash_completion
#  elif [ -f /etc/bash_completion ]; then
#    . /etc/bash_completion
#  fi
#fi

# sudo hint
if [ ! -e "$HOME/.sudo_as_admin_successful" ] && [ ! -e "$HOME/.hushlogin" ] ; then
    case " $(groups) " in *\ admin\ *|*\ sudo\ *)
    if [ -x /usr/bin/sudo ]; then
	cat <<-EOF
	To run a command as administrator (user "root"), use "sudo <command>".
	See "man sudo_root" for details.
	
	EOF
    fi
    esac
fi

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
	function command_not_found_handle {
	        # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then
		   /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
		   /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
		else
		   printf "%s: command not found\n" "$1" >&2
		   return 127
		fi
	}
fi
@consideRatio consideRatio changed the title Add bash.bashrc Colorize terminal through /etc/bash.bashrc as /home/jovyan/.bashrc tends to be wiped Feb 20, 2019
@javabrett
Copy link
Contributor

javabrett commented Feb 22, 2019

Lots of good info here - I didn't quite follow the wiped/mounted-storage bit, but I suppose it refers to the late-creation of the container runtime user account.

What about something like this - you can make use of the fact that .bashrc looks late for .bash_aliases, and co-opt that somewhat hackishly to set PS1 as you please:

docker run -it --rm jupyter/minimal-notebook bash
# hmmm, no colour prompt

tee > bash_aliases <<"EOF"
export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
EOF

docker run -it --rm -v $(pwd)/bash_aliases:/home/jovyan/.bash_aliases jupyter/minimal-notebook bash
# colour PS1!

@parente parente added the type:Enhancement A proposed enhancement to the docker images label Feb 28, 2019
@parente
Copy link
Member

parente commented Feb 28, 2019

Adding a file (bash_aliases, bashrc in skel, etc.) at build time to make the prompt prettier sounds good to me. If we copy a custom/etc/skel/.bashrc into the image before adduser in base-notebook, I think it'll get copied properly to that user's home dir. That seems like the right hook to use on the face of it, but I don't have a strong opinion on the implementation.

@javabrett
Copy link
Contributor

Customising/simplifying the base-image coloured PS1 prompt aside - is this simply a matter of setting TERM to something that supports colour:

docker run -it --rm --name jupyter -p 8888:8888 -e TERM=xterm-256color jupyter/minimal-notebook

... and when shelling-in to that, I have colour, and

$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$

This does not help for the terminal plugin in JupyterLab - something must be clearing it to TERM=xterm, but if TERM=xterm-256color is added near the top of user jovyan .bashrc, subsequent terminal shells will have coloured PS1.

@parente
Copy link
Member

parente commented Mar 13, 2019

I opened PR #826 to enable terminal colors for a couple common use cases. It doesn't address customizing the default prompt or colorizing the terminal in all possible cases (e.g., user mounts a home directory not containing a .bashrc), both of which I think would be better served through documentation of specific recipes.

Feedback welcome.

@parente
Copy link
Member

parente commented Mar 31, 2019

@consideRatio @javabrett (or anyone else) would you like to take another pass at terminal colorization to support the use cases my PR didn't handle or should we close this out?

@consideRatio
Copy link
Collaborator Author

consideRatio commented Mar 31, 2019

@parente hmmm sorry for dropping the ball on this and thanks for your work!

I'd love to see a system wide default configuration to allow the users with no .bashrc file get colors as well. For all JupyterHub's where we mount the home folder this will happen for example, and perhaps there is no real drawback to have something system wide configured rather than distributing the configuration to the home directories based on a template in /etc/skel.

I'm not a ninja when it comes to these things, how would we go about this? After reading on this unicorn based webpage I'm thinking that perhaps we should have set things in /etc/profile instead?

So for ~/.bashrc, you could edit the system wide config files /etc/bash.bashrc (for functions/aliases) or /etc/profile (for environment stuff) - you can the full list from man bash:

Oh reading further, this is what I figure we should do, we add a file to /etc/profile.d such as /etc/profile.d/colorize-term.sh.

@parente
Copy link
Member

parente commented Mar 31, 2019

Porting the lines from /etc/skel/.bashrc that enable terminal and prompt colors to a new scripta in/etc/profile.d may do the trick. The only guidance I can give is to give it a shot and try running container with various settings (e.g., no home mount, a home mount with an .bashrc already present in the host folder, a home mount without a .bashrc, etc.) and see what works and what breaks.

@romainx
Copy link
Collaborator

romainx commented Oct 21, 2020

Hello,

Just made some checks on this topic and putting those instructions in /etc/profile.d will not work since most of the shells launched in this context are non-login shells that will not execute the content of /etc/profile.d. I think the the best solution is to move what is currently done in /etc/skel/.bashrc to /etc/bash.bashrc. /etc/bash.bashrc will be executed for all interactive shells (login and not login) before executing the ~/.bashrc.
So it can answer to @consideRatio expectations and work as a system wide default configuration for color and other bash stuff.

I can draft something to test if it works as expected 😄

Here are very interesting posts on this topic:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:Enhancement A proposed enhancement to the docker images
Projects
None yet
Development

No branches or pull requests

4 participants