You can make a difference in the Apple Support Community!

When you sign up with your Apple Account, you can provide valuable feedback to other community members by upvoting helpful replies and User Tips.

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Favorite Bash profile commands

In keeping with nbar recent discussion of favorite commands, I'll start a discussion on favorite commands in your Bash profile.


I have these lines in my extended bash profile script.


# Prevent control-d from exit a console session.

# Use exit or logout.

set -o ignoreeof


# Allow editing of retrieved commands. (the up arrow)

# Use the history command to show past commands

shopt -s histverify



# I like to printout the current directory after any cd command

# Use functions so I do not have to add to the path variable.


# Print current directory after change directory command cd

alias cd='cdir'


# Define a command to change a directory and list the resulting directory

function cdir ()


{


\cd "$*"

pwd


}






# Define a new command called e.

#

# common text editor front end.

# I'm tired of nano.

#

function e ()

{

# Which os?

if [ "${OSTYPE:0:6}" = "darwin" ] ; then

# Mac OS X specific syntax

if [ -w $* ] ; then

open -a textwrangler $*

elif [ -r $* ] ; then

# use textwranglers powers to edit

open -a textwrangler $*

else

# for the tuff stuff :-(

# hints at:

# http://apple.stackexchange.com/questions/20199/how-do-i-open-a-file-as-root-in-textedit-on-lion

echo "open files with warning message. You will need to switch to panel."

echo

sudo "/Applications/Textedit.app/Contents/MacOS/TextEdit" "$*"

fi


else

# Ubuntu stuff

if [ -w $* ] ; then

gedit $*

else

gksudo gedit $*

fi

fi

}


# Define a new command called settings to list various options.

function settings ()

{

( echo "---------- env"; \

env; \

echo "--------- set"; \

set; \

echo "--------- export"; \

export; \

echo "--------- export -f"; \

export -f; \

echo "--------- alias"; \

alias; \

echo "--------- set -o"; \

set -o; \

echo "--------- shopt"; \

shopt; \

echo "--------- enable -a"; \

enable -a; ) | less


}

Posted on Jul 3, 2013 9:32 AM

Reply
Question marked as Top-ranking reply

Posted on Jul 4, 2013 1:03 PM

The following is a shell function that I use in my command prompt to display ONLY the last n subdirectory names (for example the last 3 subdirectory names). The \W which is the default PS1 magic that displays the current working directory in your promote ONLY displays the name of the directory and none of the path. The \w magic displays the entire path, which can be way too long. My __cwd() function displays the last n subdirectories


So changing your default prompt from:


    PS1="\h:\W \u\$ "

to

    PS1="\h:\$(__cwd 3) \u\$ "


#
# __cwd() - function to create current working directory prompt string.  I
#           want less than the entire path, and more than just the last
#           element in the path.  It turns out the bash prompt string can
#           execute a script function, so I created my own bit of code to
#           generate the current working directory prompt string I want.
#
# Usage:  PS1="...\$(__cwd 3)..."
#
#         Where:   3 in the above example is the number of subdirectories to
#                  keep. 3 is also the default if no value is given.
#         Output:  /
#                  /usr
#                  /usr/share
#                  /usr/share/vim
#                  /.../share/vim/vim63
#                  ~/
#                  ~/Music
#                  ~/Music/iTunes
#                  ~/Music/iTunes/iTunes\ Music  # notice spaces are honored
#                  ~/.../iTunes/iTunes\ Music/Beach Boys
#                  ~/.../iTunes\ Music/Beach\ Boys/Made\ in\ the\ U.S.A.
#
__cwd()
{
    n="${1:-3}"             # if no dir count, default to 3
    p="#${PWD}"             # add # so after split # represents the root dir
    IFS="/"                 # split on directory divider '/'
    set ${p/#\#${HOME}/\~}  # Replace #$HOME with ~ and split into dir parts
    p="${1}"                # ${1} has # or ~, save it
    shift $(($#-(n+1) < 0 ? 0 : $#-(n+1)))   # remove excess leading dirs
    [[ "${1}" != [#~]* ]] && p="${p}/..."    # ... represents a partial path
    for ((j=2; j<n+2; j++)); do p="${p}/${!j}"; done # append last n dirs
    while [[ "${p}" = [#/]/* ]]; do p="${p#?}"; done # del leading /'s and #
    while [[ "${p}" = *[^~]/ ]]; do p="${p%?}"; done # del trailing /'s
    printf "%q" "${p}"      # generate path str w/shell magic chars quoted
}


As my professors used to say: "Figuring out how __cwd() works is left as an exercise for the student." 🙂


In reality, my PS1 prompt is much more complex. I also colorize my prompt. For example:


    PS1="\D{%a@%R}[\[\e[44;36;1m\]\h\[\e[0m\]]\[\e[34;1m\]\$(__cwd 3)\[\e[0m\]> "


This will generate a prompt similar to the following:


    Thu@15:09[BobBookPro]~/.../iTunes/iTunes\ Music/Beatles>


Where 'BobBookPro' will be Cyan text on Blue (I couldn't get the forum to generate the blue background, but it really does look nice when you see it on the actual terminal. And the "~/.../iTunes/iTunes\ Music/Beatles" will be Blue.


Where:


\D{%a@%R} is prompt magic to substitute the day of the week @ time of day.


All the \[...\] notation tells the prompt that non-printing character codes are happening between. In this case the color codes are inside the \[...\]


  • \e[44;36;1m says cyan text on blue
  • \e[34;1m says blue text


\h is the computer name. If you are having any problems getting the Mac to always use your System Preferences -> Sharing -> Computer name, you could replace "\h" with "$(networksetup -getcomputername)"


#
# Prompt Colors
#         -foreground- ----bold---- -underline-- --reverse---   -background-
# black         \e[30m     \e[30;1m     \e[30;4m     \e[30;7m    \e[40;fg;1m
# red           \e[31m     \e[31;1m     \e[31;4m     \e[31;7m    \e[41;fg;1m
# green         \e[32m     \e[32;1m     \e[32;4m     \e[32;7m    \e[42;fg;1m
# yellow        \e[33m     \e[33;1m     \e[33;4m     \e[33;7m    \e[43;fg;1m
# blue          \e[34m     \e[34;1m     \e[34;4m     \e[34;7m    \e[44;fg;1m
# magenta       \e[35m     \e[35;1m     \e[35;4m     \e[35;7m    \e[45;fg;1m
# cyan          \e[36m     \e[36;1m     \e[36;4m     \e[36;7m    \e[46;fg;1m
# White         \e[37m     \e[37;1m     \e[37;4m     \e[37;7m    \e[47;fg;1m
#
# Reset         \e[0m
#


I have several different Mac, Linux, Solaris, AIX system I work with on a regular basis. I use different hostname colors so it is easier for me to see by the color with terminal window I'm currently using. Also when I'm scrolling through my scroll back history, the colored prompts make it easy to see the commands vs the output, which is very useful if the output is very long.


Message was edited by: BobHarris

10 replies
Question marked as Top-ranking reply

Jul 4, 2013 1:03 PM in response to rccharles

The following is a shell function that I use in my command prompt to display ONLY the last n subdirectory names (for example the last 3 subdirectory names). The \W which is the default PS1 magic that displays the current working directory in your promote ONLY displays the name of the directory and none of the path. The \w magic displays the entire path, which can be way too long. My __cwd() function displays the last n subdirectories


So changing your default prompt from:


    PS1="\h:\W \u\$ "

to

    PS1="\h:\$(__cwd 3) \u\$ "


#
# __cwd() - function to create current working directory prompt string.  I
#           want less than the entire path, and more than just the last
#           element in the path.  It turns out the bash prompt string can
#           execute a script function, so I created my own bit of code to
#           generate the current working directory prompt string I want.
#
# Usage:  PS1="...\$(__cwd 3)..."
#
#         Where:   3 in the above example is the number of subdirectories to
#                  keep. 3 is also the default if no value is given.
#         Output:  /
#                  /usr
#                  /usr/share
#                  /usr/share/vim
#                  /.../share/vim/vim63
#                  ~/
#                  ~/Music
#                  ~/Music/iTunes
#                  ~/Music/iTunes/iTunes\ Music  # notice spaces are honored
#                  ~/.../iTunes/iTunes\ Music/Beach Boys
#                  ~/.../iTunes\ Music/Beach\ Boys/Made\ in\ the\ U.S.A.
#
__cwd()
{
    n="${1:-3}"             # if no dir count, default to 3
    p="#${PWD}"             # add # so after split # represents the root dir
    IFS="/"                 # split on directory divider '/'
    set ${p/#\#${HOME}/\~}  # Replace #$HOME with ~ and split into dir parts
    p="${1}"                # ${1} has # or ~, save it
    shift $(($#-(n+1) < 0 ? 0 : $#-(n+1)))   # remove excess leading dirs
    [[ "${1}" != [#~]* ]] && p="${p}/..."    # ... represents a partial path
    for ((j=2; j<n+2; j++)); do p="${p}/${!j}"; done # append last n dirs
    while [[ "${p}" = [#/]/* ]]; do p="${p#?}"; done # del leading /'s and #
    while [[ "${p}" = *[^~]/ ]]; do p="${p%?}"; done # del trailing /'s
    printf "%q" "${p}"      # generate path str w/shell magic chars quoted
}


As my professors used to say: "Figuring out how __cwd() works is left as an exercise for the student." 🙂


In reality, my PS1 prompt is much more complex. I also colorize my prompt. For example:


    PS1="\D{%a@%R}[\[\e[44;36;1m\]\h\[\e[0m\]]\[\e[34;1m\]\$(__cwd 3)\[\e[0m\]> "


This will generate a prompt similar to the following:


    Thu@15:09[BobBookPro]~/.../iTunes/iTunes\ Music/Beatles>


Where 'BobBookPro' will be Cyan text on Blue (I couldn't get the forum to generate the blue background, but it really does look nice when you see it on the actual terminal. And the "~/.../iTunes/iTunes\ Music/Beatles" will be Blue.


Where:


\D{%a@%R} is prompt magic to substitute the day of the week @ time of day.


All the \[...\] notation tells the prompt that non-printing character codes are happening between. In this case the color codes are inside the \[...\]


  • \e[44;36;1m says cyan text on blue
  • \e[34;1m says blue text


\h is the computer name. If you are having any problems getting the Mac to always use your System Preferences -> Sharing -> Computer name, you could replace "\h" with "$(networksetup -getcomputername)"


#
# Prompt Colors
#         -foreground- ----bold---- -underline-- --reverse---   -background-
# black         \e[30m     \e[30;1m     \e[30;4m     \e[30;7m    \e[40;fg;1m
# red           \e[31m     \e[31;1m     \e[31;4m     \e[31;7m    \e[41;fg;1m
# green         \e[32m     \e[32;1m     \e[32;4m     \e[32;7m    \e[42;fg;1m
# yellow        \e[33m     \e[33;1m     \e[33;4m     \e[33;7m    \e[43;fg;1m
# blue          \e[34m     \e[34;1m     \e[34;4m     \e[34;7m    \e[44;fg;1m
# magenta       \e[35m     \e[35;1m     \e[35;4m     \e[35;7m    \e[45;fg;1m
# cyan          \e[36m     \e[36;1m     \e[36;4m     \e[36;7m    \e[46;fg;1m
# White         \e[37m     \e[37;1m     \e[37;4m     \e[37;7m    \e[47;fg;1m
#
# Reset         \e[0m
#


I have several different Mac, Linux, Solaris, AIX system I work with on a regular basis. I use different hostname colors so it is easier for me to see by the color with terminal window I'm currently using. Also when I'm scrolling through my scroll back history, the colored prompts make it easy to see the commands vs the output, which is very useful if the output is very long.


Message was edited by: BobHarris

Jul 4, 2013 1:22 PM in response to rccharles

The beginning of my 'bash' shell initialization scripts (.bash_profile and .bashrc) is the following statement:


[[ ${-#*i}  = ${-} ]] && return


This will determine if 'bash' is being started as an interactive session, or as part of a non-interactive invocation, such as when I'm running a via ssh, scp, or running a script that creates a sub-shell as a side effect, and I do not want my rather large shell initialization file(s) to mess things up.


$- will return the 'bash' shell options, one of which will be the letter 'i' if this is an interactive session. So the ${-#*i} will delete the beginning of the string up to an including an 'i', or do nothing if there is no 'i' in the option string. I then compare the result against the original $- string. If both are identical, then 'i' did not exist in the option string, and thus this is not an interactive session, and I do NOT want to execute my 'bash' shell initialization script.

Jul 4, 2013 1:27 PM in response to rccharles

My .bash_profile includes


source $HOME/.bashrc


This is because 'bash' will ONLY run your .bash_profile (or .bash_login, or .profile) when initially logging in, but will not run your .bashrc.


However, when 'bash' starts a subshell, it will ONLY invoke your .bashrc file.


So you put stuff that ONLY needs to be execute once per login in your .bash_profile, such as environment variable setup, stty terminal settings, your PS1 prompt, etc...


Things that need to be specified each time you start a sub-shell, such as shell functions, command aliases, etc... you put in your .bashrc.

But when you are first logging in, you want BOTH, so you have your .bash_profile source your .bashrc


Message was edited by: BobHarris

Jul 4, 2013 3:52 PM in response to BobHarris

Thanks for the idea of colorizing my bash prompt.


I'm confused by the excaping.

I see this at the end of your prompt. seems like the first \[ doesn't match any thing.


\[\e[0m\]> "


Why do you write the color codes as:

\e[34;1m says blue text

I'd of written them after looking at the actual $PS1 variable as. I've added the ending \]:

\e[34;1m\] says blue text

Jul 4, 2013 8:07 PM in response to Mark Jalbert

Mark Jalbert wrote:


My .bash_profile simply reads ->

source .bashrc

Bash isn't my login shell nor do I want it to read .profile. Other than aliases and a few functions, I let the operating system configure my bash shell when I invoke bash as a login shell. Rather boring....

If you prefer you other shell, that is perfectly OK. I'm not sure if the tricks I've posted will all work as shown in other shells, but some of the concepts will work.


If you want 'bash' as your default shell, you could change it on your Mac via System Preferences -> Users & Groups (formally Accounts). Click on the Padlock in the lower left corner, and authenticate yourself as admin. Control-Click on your account, and select "Advanced Options..." Change the "Login Shell" to /bin/bash via the pick list.


If this is another Unix OS where you wish to use 'bash', you might look at the chsh command, but if your company has networked authentication via NIS (aka Yellowpages), or LDAP, etc... you may need to work with your company's IT group to get your shell changed.


As an alternative, you could just put the following in the default shell's login script:


exec /bin/bash --login


and then make sure that you have a .bash_profile, just in case your default shell also uses .profile, as you do not want to get into an infinite loop 🙂


Again, if you like your default shell, no need to change anything. I used to be a 'csh/tcsh' user for years, and before that I was a bourne shell user (with some years before and after using VAX/VMS DCL 😀 ). About 6 years ago I made the decision to switch from 'tcsh' to 'bash', but that is no reason for anyone else to switch to 'bash'

Jul 4, 2013 8:22 PM in response to rccharles

Thanks for the idea of colorizing my bash prompt.


Your welcome. I have found colorized prompts to be extremely useful, whether working on a single system, and even more so when working with multiple systems (which I've been forever, I just didn't have colorized prompts on my 80 column card punch 🙂 )

I'm confused by the escaping.

I see this at the end of your prompt. seems like the first \[ doesn't match any thing.


\[\e[0m\]> "


Why do you write the color codes as:

\e[34;1m says blue text

I'd of written them after looking at the actual $PS1 variable as. I've added the ending \]:

\e[34;1m\] says blue text


The ANSI color escape sequence is <escape>[34;1m That is what tells the terminal to change color to bold blue.


<escape>[0m tells the terminal to reset to default color


The \[stuff in the middle\] is bash prompt notation for command line editing to tell bash that the "stuff in the middle" does not change the cursor position so when editing the command line, bash knows where the prompt ends on the terminal, and where the command begins, where the command should have wrapped to the next line, etc...


Remember the shell is NOT the display device, and the shell is NOT editing the actual display buffer. It is sending out more escape sequences to position the cursor and write characters based on what it things is on the screen and where it thinks it is located. If it does not know that the color escape sequence does not move the cursor, then bash will think the prompt is longer than it really is.


That is why I described the \[...\] notation separately from the actual ANSI color escape sequence.

It is just a style choice I made, but I can also see where \[\e[34;1m\] and \[\e[0m\] can be easier to describe when ONLY taking about the bash shell prompt.


However, outputting ANSI terminal color sequences can be done from other script and there the \[...\] notation does not apply. \[...\] is strictly limited to the bash shell prompt strings.

Jul 4, 2013 9:29 PM in response to BobHarris

I have my Terminal setup as 256 colors. In my .bashrc file:


export TERM=xterm-256color

/usr/bin/tput init


I discovered a 256 color generator at the following location that providing the Terminal is set to 256 colors, will output the color number and its hex code equivalent in the actual colors.


github.com/majnemer/davesdots/blob/master/colortest.pl


Having the color number comes in handy for the following step:


Bluebld="$(tput bold; tput setaf 63)"

White="$(tput setaf 15)"


export PS1='\[$Bluebld\]\h: \w$ \[$White\]'j


This gives a blue prompt with white text.


User uploaded file


alias clear='tput clear'


The above syntax is also portable to Fedora and Ubuntu.

Jul 5, 2013 9:54 AM in response to BobHarris

Thanks for the explanation.


I just didn't have colorized prompts on my 80 column card punch


You could have used different cardpunches with different ribbons on them 😝. In my student days, the rare cardpunch had a new ribbon producing dark black lettering. These cards stood out. Most produced a faded, barely readable grey.


Robert

Favorite Bash profile commands

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.