User Tools

Site Tools


public:techstuff:advancedbash

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
public:techstuff:advancedbash [2012/08/21 13:51] – Deleted by PageMove plugin nathanpublic:techstuff:advancedbash [2020/04/25 13:05] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== 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>
 + <nowiki> export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '</nowiki>
 +Set the above <code>PS1</code> variable in <code>~/.bashrc</code> and export it.
 +
 +<b>Red for root:</b><br>
 + <nowiki> export PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] '</nowiki>
 +Set the above <code>PS1</code> variable in <code>/root/.bashrc</code> 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
 + <nowiki> #set xterm title
 + case "$TERM" in
 +   xterm | xterm-color)
 +     XTERM_TITLE='\[\033]0;\W@\u@\H\007\]'
 +   ;;
 + esac;</nowiki>
 +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;\$((COLUMNS-4))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"
 + <span style="color: white; background-color: lightblue"><b>lol</b></span>
 +
 +Use in prompt (note double quotes and <nowiki>\[ \]</nowiki> 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.
 + <nowiki>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 " "'</nowiki>
 +
 +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 [[public:nathan:techstuff:ipallocations]]:
 + <nowiki>#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;)'</nowiki>
 +
 +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:
 + <nowiki>PS1="\[$WHITE\]$RET_VALUE $RET_SMILEY \[$BLUE\]\u\[$RED\]@\[$EBLUE\]\h\[$WHITE\] \W \[$ERED\]\\$\[$EWHITE\] "</nowiki>
 +
 +==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 <code>.bashrc</code> 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 <code>.bashrc</code> 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