# Declare and fill variables providing ANSI colors enclosed between # \[ and \], as per the "PROMPTING" section of man bash: function declare_colors { local ci cj cn c_normal='\[\e[0m\]' for cn in {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do eval "c_${cn}='\[\e[${ci:=0};${cj:=30}m\]'" ((++cj,(cj==38)?(cj=30,++ci):1)) done } function disable_colors { local cn for cn in normal {,bright_}{black,red,green,yellow,blue,magenta,cyan,white}; do eval "c_${cn}=''" done } # Generate the PS1 variable; doing that in a function allows to reflect almost # anything in the prompt. function generate_ps1 { # Save the return code value (rcv) local rcv=$? # Color for brackets and braces local bc="${c_red}" # Pick the return code color (rcc) local rcc='c_bright_green' [ $rcv -ne 0 ] && rcc='c_bright_red' local rc dstamp tstamp user host cwdir es rc=$( printf "%s[%s${rcv}%s]" "${bc}" "${!rcc}" "${bc}") tstamp=$( printf '[%s\\t%s]' "${c_bright_yellow}" "${bc}") user=$( printf '[%s\\u%s]' "${c_cyan}" "${bc}") host=$( printf '{%s\\h%s}' "${c_cyan}" "${bc}") cwdir=$( printf '%s\w%s ' "${c_green}" "${c_normal}") es=$( printf '%s\$%s ' "${c_red}" "${c_normal}") if [ "${PS1_DISPLAY_DATE}" ]; then dstamp=$(printf '[%s\\D{%%F}%s]' "${c_bright_yellow}" "${bc}") fi PS1="${rc}${dstamp}${tstamp}${user}${host}${cwdir}${es}" # Also set PS2 and PS4: PS2="${c['bright_green']}" PS4="+ ${c['cyan']}[trace]${c['normal']} " # It makes sense to export PS4 (so that e.g. "bash foobar.sh" benefit from # it): export PS4 } # Provide a helper function to swiftly enable or disable the date in the # prompt: function ps1_toggle_date { if [ "${PS1_DISPLAY_DATE}" ]; then unset PS1_DISPLAY_DATE else PS1_DISPLAY_DATE='yes' fi } # Provide a helper function to swiftly enable or disable colors in the # prompt: function ps1_toggle_colors { if [ "${PS1_USE_COLORS}" ]; then unset PS1_USE_COLORS disable_colors else declare_colors PS1_USE_COLORS='yes' fi } # Provide a helper function to swiftly reduce the prompt to '$ ' -- this is # useful e.g. for documentation purposes, when one wants to run a few commands # and copy the whole terminal output without the prompt (which usually reflects # undesired details such as user and hostname): function ps1_toggle_prompt { local min_prompt='\$ ' if [ "${PS1}" == "${min_prompt}" ]; then PROMPT_COMMAND='generate_ps1' generate_ps1 else unset PROMPT_COMMAND PS1="${min_prompt}" fi } # By default, use colors but do not display the date: ps1_toggle_colors #ps1_toggle_date # Instruct bash to regenerate PS1 before printing the prompt: PROMPT_COMMAND='generate_ps1' # Generate PS1 at least once: generate_ps1