User Tools

Site Tools


public:techstuff:advancedbash

Advanced Bash

Summary

There are a variety possibilities for your bash prompt, and customizing it will help you be more productive at the command line. You can add additional information to your prompt, or you can simply color it to make the prompt stand out.

Basic Prompts

The following settings are useful for distinguishing the root prompt from non-root users:

<b>Green for regular users:</b><br> export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' Set the above

PS1

variable in

~/.bashrc

and export it.

<b>Red for root:</b><br> export PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] ' Set the above

PS1

variable in

/root/.bashrc

and export it.

Distinct root and non-root Prompts

Use 2 separate config files; one for root (/root/.bash_profile), and one for normal user (~/.bashrc): vim ~/.bashrc Comment out the default PS1: #PS1='[\u@\h \W]\$ ' Use the following prompt for normal user: PS1='\[\e[0;32m\]\u \[\e[1;34m\]\w \[\e[1;32m\]\$ \[\e[1;37m\] ' It features username in green, working directory in bright blue, a bright green $ prompt, and bright white text-type.

Edit root prompt: sudo vim /root/.bash_profile Comment out default: #PS1='[\u@\h \W]\$ ' Use the following prompt for root: PS1='\[\e[0;31m\]\u \[\e[1;34m\]\w \[\e[0;31m\]\$ \[\e[0;32m\] '

It features username 'root' in red, working directory in bright blue, a red '#' for su designation, and text-typing in a nasty, matrix-like, Type-O-Negative green. ;)

Here is the bash color code:

Black 0;30 Dark Gray 1;30 Blue 0;34 Light Blue 1;34 Green 0;32 Light Green 1;32 Cyan 0;36 Light Cyan 1;36 Red 0;31 Light Red 1;31 Purple 0;35 Light Purple 1;35 Brown 0;33 Yellow 1;33 Light Gray 0;37 White 1;37

Replace digit 0 with 1 to get bright color version! Experiment as desired, and see bash manpage excerpt below to further customize backslash-escaped special characters.

'Tip': \[ begins a sequence of non-printing characters \] ends a sequence of non-printing characters

Customize your Bash prompt further

*Edit your ~/.bashrc by commenting out the default Arch prompt:

# PS1='[\u@\h \W]\$ ' *Add the following entries to your ~/.bashrc BLUE=`tput setf 1` GREEN=`tput setf 2` CYAN=`tput setf 3` RED=`tput setf 4` MAGENTA=`tput setf 5` YELLOW=`tput setf 6` WHITE=`tput setf 7` PS1='\[$GREEN\]\u@\h \[$BLUE\]\w/\[$GREEN\] \$\[$WHITE\] '

The \[ and \] are necessary to not get line-wrapping problems on the terminal.

Then do: source ~/.bashrc You may wish to edit your /root/.bashrc with a similar set of entries, perhaps with RED to indicate \u.

the various \x's (ripped from bash manpage):

Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:

\a an ASCII bell character (07)

 \d         the date in "Weekday Month Date" format (e.g., "Tue May 26")
 \D{format} the format is passed to strftime(3) and the result
            is inserted into the prompt string an empty format
            results in a locale-specific time representation.
            The braces are required
 \e         an ASCII escape character (033)
 \h         the hostname up to the first `.'
 \H         the hostname
 \j         the number of jobs currently managed by the shell
 \l         the basename of the shell's terminal device name
 \n         newline
 \r         carriage return
 \s         the name of the shell, the basename of $0 (the portion following
            the final slash)
 \t         the current time in 24-hour HH:MM:SS format
 \T         the current time in 12-hour HH:MM:SS format
 \@         the current time in 12-hour am/pm format
 \A         the current time in 24-hour HH:MM format
 \u         the username of the current user
 \v         the version of bash (e.g., 2.00)
 \V         the release of bash, version + patch level (e.g., 2.00.0)
 \w         the current working directory, with $HOME abbreviated with a tilde
 \W         the basename of the current working directory, with $HOME
            abbreviated with a tilde
 \!         the history number of this command
 \#         the command number of this command
 \$         if the effective UID is 0, a #, otherwise a $
 \nnn       the character corresponding to the octal number nnn
 \\         a backslash
 \[         begin a sequence of non-printing characters, which could be used
            to embed a terminal control sequence into the prompt
 \]         end a sequence of non-printing characters
        
 The command number and the history number are usually different:
 the history number of a command is its position in the history
 list, which may include commands restored from the history file
 (see HISTORY below), while the command number is the position in
 the sequence of commands executed during the current shell session.
 After the string is decoded, it is expanded via parameter
 expansion, command substitution, arithmetic expansion, and quote
 removal, subject to the value of the promptvars shell option (see
 the description of the shopt command under SHELL BUILTIN COMMANDS
 below).
Set xterm window title

Add this code fragment to you .bashrc #set xterm title case "$TERM" in xterm | xterm-color) XTERM_TITLE='\[\033]0;\W@\u@\H\007\]' ;; esac; And since there you can use ${XTERM_TITLE} macro at begining of PS1 to set xterm title (if available) to directory@user@hostname. Or you can modify it (XTERM_TITLE=… line) using regular PS1 escape sequencies.

Positioning the Cursor

The following sequence sets the cursor position:

\[\033[<row>;<column>f\]

The current cursor position can be saved using

\[\033[s\]

To restore a position, use the following sequence:

\[\033[u\]

The following example uses these sequences to display the time in the upper right corner:

PS1=“>\[\033[s\]\[\033[1;\$1)f\]\$(date +%H:%M)\[\033[u\]”

The environment variable COLUMNS contains the number of columns of the terminal. The above example substracts 4 from its value in order to justify the five character wide output of date at the right border.

List of colors for prompt and bash

Add this to your .bashrc to use colors in prompt and commands:

<pre>TXTBLK='\e[0;30m' # Black - Regular TXTRED='\e[0;31m' # Red TXTGRN='\e[0;32m' # Green TXTYLW='\e[0;33m' # Yellow TXTBLU='\e[0;34m' # Blue TXTPUR='\e[0;35m' # Purple TXTCYN='\e[0;36m' # Cyan TXTWHT='\e[0;37m' # White BLDBLK='\e[1;30m' # Black - Bold BLDRED='\e[1;31m' # Red BLDGRN='\e[1;32m' # Green BLDYLW='\e[1;33m' # Yellow BLDBLU='\e[1;34m' # Blue BLDPUR='\e[1;35m' # Purple BLDCYN='\e[1;36m' # Cyan BLDWHT='\e[1;37m' # White UNDBLK='\e[4;30m' # Black - Underline UNDRED='\e[4;31m' # Red UNDGRN='\e[4;32m' # Green UNDYLW='\e[4;33m' # Yellow UNDBLU='\e[4;34m' # Blue UNDPUR='\e[4;35m' # Purple UNDCYN='\e[4;36m' # Cyan UNDWHT='\e[4;37m' # White BAKBLK='\e[40m' # Black - Background BAKRED='\e[41m' # Red BAKGRN='\e[42m' # Green BAKYLW='\e[43m' # Yellow BAKBLU='\e[44m' # Blue BAKPUR='\e[45m' # Purple BAKCYN='\e[46m' # Cyan BAKWHT='\e[47m' # White TXTRST='\e[0m' # Text Reset</pre>

Use in commands (use curly brackets only if you need to specify text right after value '$TXTBLU lol' or '${TXTBLU}lol'): harvie@harvie-ntb ~ $ echo -e “${TXTBLU}lol” <font color='blue'>lol</font> harvie@harvie-ntb ~ $ echo -e “${BLDBLU}lol” <font color='lightblue'><b>lol</b></font> harvie@harvie-ntb ~ $ echo -e “${UNDBLU}lol” <font color='lightblue'><b><u>lol</u></b></font> harvie@harvie-ntb ~ $ echo -e “${BAKBLU}lol” <b>lol</b>

Use in prompt (note double quotes and \[ \] used by bash to count prompt lenght in characters well): PS1=“\[$TXTBLU\]foo\[$TXTRED\] bar\[$TXTRST\] baz : ”

Return value visualisation

You can add this line to the end of your .bashrc if you want to see return value of last executed command. This should work with any kind of prompt as long as it don't need PROMPT_COMMAND. PROMPT_COMMAND='RET=$?; if [[public:nathan:techstuff:ipallocations]]; then echo -ne "\033[0;32m$RET\033[0m ;)"; else echo -ne "\033[0;31m$RET\033[0m ;("; fi; echo -n " "'

It will look like this: <font color=“green”>0</font><b> ;) </b>harvie@harvie-ntb ~/ $ true <font color=“green”>0</font><b> ;) </b>harvie@harvie-ntb ~/ $ false <font color=“red”>1</font><b> ;( </b>harvie@harvie-ntb ~/ $ Zero is green and non-zero is red. There is also smiley (you can replace it with anything what you want). So your bash will smile if last operation was succesful.

Better return value visualisation

If you want colors, you need to set $RED and $GREEN values: RED='\e[0;31m' GREEN='\e[0;32m'

You have to specify this values in ipallocations: #return value visualisation PROMPT_COMMAND='RET=$?;' RET_VALUE='$(echo $RET)' #Ret value not colorized - you can modify it. RET_SMILEY='$(if [[public:nathan:techstuff:ipallocations]]; then echo -ne "\[$GREEN\];)"; else echo -ne "\[$RED\];("; fi;)'

Then you can use $RET_VALUE and $RET_SMILEY macros in PS1 (prompt). Note that you need use double quotes: #prompt PS1=“$RET_VALUE $RET_SMILEY : ”

This will give you basic prompt : 0 <font color=“green”>;)</font> : true 0 <font color=“green”>;)</font> : false 1 <font color=“red”>;(</font> :

But you will probably want to use $RET_VALUE or $RET_SMILEY in your own prompt. like me: PS1="\[$WHITE\]$RET_VALUE $RET_SMILEY \[$BLUE\]\u\[$RED\]@\[$EBLUE\]\h\[$WHITE\] \W \[$ERED\]\\$\[$EWHITE\] "

Advanced Prompts

Wolfman's

After reading through most of the [http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/index.html Bash Prompt Howto], I developed a color bash prompt that displays the last 25 characters of the current working directory. This prompt should work well on terminals with a black background. The following code goes in your home directory's

.bashrc

file.

*Comment out Arch's default prompt. # PS1='[\u@\h \W]\$ '

*Next add the bash_prompt_command function. If you have a couple directories with long names or start entering a lot of subdirectories, this function will keep the command prompt from wrapping around the screen by displaying at most the last pwdmaxlen characters from the PWD. This code was taken from the Bash Prompt Howto's section on [http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x783.html Controlling the Size and Appearance of $PWD] and modified to replace the user's home directory with a tilde. ################################################## # Fancy PWD display function ################################################## # The home directory (HOME) is replaced with a ~ # The last pwdmaxlen characters of the PWD are displayed # Leading partial directory names are striped off # /home/me/stuff → ~/stuff if USER=me # /usr/share/big_dir_name → ../share/big_dir_name if pwdmaxlen=20 ################################################## bash_prompt_command() {

   # How many characters of the $PWD should be kept
   local pwdmaxlen=25
   # Indicate that there has been dir truncation
   local trunc_symbol=".."
   local dir=${PWD##*/}
   pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen ))
   NEW_PWD=${PWD/#$HOME/\~}
   local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen ))
   if [ ${pwdoffset} -gt "0" ]
   then
       NEW_PWD=${NEW_PWD:$pwdoffset:$pwdmaxlen}
       NEW_PWD=${trunc_symbol}/${NEW_PWD#*/}
   fi

}

*This code generates the command prompt. There's not much to this. A bunch of colors are defined. The user's color for the username, hostname, and prompt ($ or #) is set to cyan, and if the user is root (root's UID is always 0), set the color to red. The command prompt is set to a colored version of Arch's default with the NEW_PWD from the last function. *Also, make sure that your color variables are enclosed in double and not single quote marks. Using single quote marks seems to give bash problems with line wrapping correctly. bash_prompt() {

   case $TERM in
    xterm*|rxvt*)
        local TITLEBAR='\[\033]0;\u:${NEW_PWD}\007\]'
         ;;
    *)
        local TITLEBAR=""
         ;;
   esac
   local NONE="\[\033[0m\]"    # unsets color to term's fg color
   
   # regular colors
   local K="\[\033[0;30m\]"    # black
   local R="\[\033[0;31m\]"    # red
   local G="\[\033[0;32m\]"    # green
   local Y="\[\033[0;33m\]"    # yellow
   local B="\[\033[0;34m\]"    # blue
   local M="\[\033[0;35m\]"    # magenta
   local C="\[\033[0;36m\]"    # cyan
   local W="\[\033[0;37m\]"    # white
   
   # emphasized (bolded) colors
   local EMK="\[\033[1;30m\]"
   local EMR="\[\033[1;31m\]"
   local EMG="\[\033[1;32m\]"
   local EMY="\[\033[1;33m\]"
   local EMB="\[\033[1;34m\]"
   local EMM="\[\033[1;35m\]"
   local EMC="\[\033[1;36m\]"
   local EMW="\[\033[1;37m\]"
   
   # background colors
   local BGK="\[\033[40m\]"
   local BGR="\[\033[41m\]"
   local BGG="\[\033[42m\]"
   local BGY="\[\033[43m\]"
   local BGB="\[\033[44m\]"
   local BGM="\[\033[45m\]"
   local BGC="\[\033[46m\]"
   local BGW="\[\033[47m\]"
   
   local UC=$W                 # user's color
   [ $UID -eq "0" ] && UC=$R   # root's color
   
   PS1="$TITLEBAR ${EMK}[${UC}\u${EMK}@${UC}\h ${EMB}\${NEW_PWD}${EMK}]${UC}\\$ ${NONE}"
   # without colors: PS1="[\u@\h \${NEW_PWD}]\\$ "
   # extra backslash in front of \$ to make bash colorize the prompt

}

*Finally, append this code. This ensures that the NEW_PWD variable will be updated when you cd somewhere else, and it sets the PS1 variable, which contains the command prompt. PROMPT_COMMAND=bash_prompt_command bash_prompt unset bash_prompt

*If you want to play around with the colors of this prompt, open your

.bashrc

file in a text editor. When you want to see what the new prompt looks like, enter the following from your home directory, and the prompt will immediately change. $ source ~/.bashrc

1)
COLUMNS-4
public/techstuff/advancedbash.txt · Last modified: 2020/04/25 13:05 by 127.0.0.1