Your interaction with Linux Bash shell will become very pleasant, if you use PS1, PS2, PS3, PS4, and PROMPT_COMMAND effectively. PS stands for prompt statement. This article will give you a jumpstart on the Linux command prompt environment variables using simple examples.
1. PS1 – Default interaction prompt
The default interactive prompt on your Linux can be modified as shown below to something useful and informative. In the following example, the default PS1 was “\s-\v\$”, which displays the shell name and the version number. Let us change this default behavior to display the username, hostname and current working directory name as shown below.
-bash-3.2$ export PS1="\u@\h \w> "
ramesh@dev-db ~> cd /etc/mail
ramesh@dev-db /etc/mail>
[Note: Prompt changed to "username@hostname current-dir>" format]
Following PS1 codes are used in this example:
- \u – Username
- \h – Hostname
- \w – Full pathname of current directory. Please note that when you are in the home directory, this will display only ~ as shown above
- Note that there is a space at the end in the value of PS1. Personally, I prefer a space at the end of the prompt for better readability.
Make this setting permanent by adding export PS1=”\u@\h \w> ” to either .bash_profile (or) .bashrc as shown below.
ramesh@dev-db ~> vi ~/.bash_profile (or)
ramesh@dev-db ~> vi ~/.bashrc
[Note: Add export PS1="\u@\h \w> " to one of the above files]
In the next post, I’ll write about several practical examples of PS1 usage in detail.
2. PS2 – Continuation interactive prompt
A very long unix command can be broken down to multiple line by giving \ at the end of the line. The default interactive prompt for a multi-line command is “> “. Let us change this default behavior to display “continue->” by using PS2 environment variable as shown below.
ramesh@dev-db ~> myisamchk --silent --force --fast --update-state \
> --key_buffer_size=512M --sort_buffer_size=512M \
> --read_buffer_size=4M --write_buffer_size=4M \
> /var/lib/mysql/bugs/*.MYI
[Note: This uses the default ">" for continuation prompt]
ramesh@dev-db ~> export PS2="continue-> "
ramesh@dev-db ~> myisamchk --silent --force --fast --update-state \
continue-> --key_buffer_size=512M --sort_buffer_size=512M \
continue-> --read_buffer_size=4M --write_buffer_size=4M \
continue-> /var/lib/mysql/bugs/*.MYI
[Note: This uses the modified "continue-> " for continuation prompt]
I found it very helpful and easy to read, when I break my long commands into multiple lines using \. I have also seen others who don’t like to break-up long commands. What is your preference? Do you like breaking up long commands into multiple lines?
3. PS3 – Prompt used by “select” inside shell script
You can define a custom prompt for the select loop inside a shell script, using the PS3 environment variable, as explained below.
Shell script and output WITHOUT PS3:
ramesh@dev-db ~> cat ps3.sh
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done
ramesh@dev-db ~> ./ps3.sh
1) mon
2) tue
3) wed
4) exit
#? 1
Monday
#? 4
[Note: This displays the default "#?" for select command prompt]
Shell script and output WITH PS3:
ramesh@dev-db ~> cat ps3.sh
PS3="Select a day (1-4): "
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done
ramesh@dev-db ~> ./ps3.sh
1) mon
2) tue
3) wed
4) exit
Select a day (1-4): 1
Monday
Select a day (1-4): 4
[Note: This displays the modified "Select a day (1-4): "
for select command prompt]
4. PS4 – Used by “set -x” to prefix tracing output
The PS4 shell variable defines the prompt that gets displayed, when you execute a shell script in debug mode as shown below.
Shell script and output WITHOUT PS4:
ramesh@dev-db ~> cat ps4.sh
set -x
echo "PS4 demo script"
ls -l /etc/ | wc -l
du -sh ~
ramesh@dev-db ~> ./ps4.sh
++ echo 'PS4 demo script'
PS4 demo script
++ ls -l /etc/
++ wc -l
243
++ du -sh /home/ramesh
48K /home/ramesh
[Note: This displays the default "++" while tracing the output using set -x]
Shell script and output WITH PS4:
The PS4 defined below in the ps4.sh has the following two codes:
- $0 – indicates the name of script
- $LINENO – displays the current line number within the script
ramesh@dev-db ~> cat ps4.sh
export PS4='$0.$LINENO+ '
set -x
echo "PS4 demo script"
ls -l /etc/ | wc -l
du -sh ~
ramesh@dev-db ~> ./ps4.sh
../ps4.sh.3+ echo 'PS4 demo script'
PS4 demo script
../ps4.sh.4+ ls -l /etc/
../ps4.sh.4+ wc -l
243
../ps4.sh.5+ du -sh /home/ramesh
48K /home/ramesh
[Note: This displays the modified "{script-name}.{line-number}+"
while tracing the output using set -x]
5. PROMPT_COMMAND
Bash shell executes the content of the PROMPT_COMMAND just before displaying the PS1 variable.
ramesh@dev-db ~> export PROMPT_COMMAND="date +%k:%m:%S"
22:08:42
ramesh@dev-db ~>
[Note: This displays the PROMPT_COMMAND and PS1 output on different lines]
If you want to display the value of PROMPT_COMMAND in the same line as the PS1, use the echo -n as shown below.
ramesh@dev-db ~> export PROMPT_COMMAND="echo -n [$(date +%k:%m:%S)]"
[22:08:51]ramesh@dev-db ~>
[Note: This displays the PROMPT_COMMAND and PS1 output on the same line]
If you liked this article, please bookmark it on del.icio.us and Stumble using the link provided below, under ‘What Next?’ section.






My name is Ramesh Natarajan. I will be posting instruction guides, how-to, troubleshooting tips and tricks on Linux, database, hardware, security and web. My focus is to write articles that will either teach you or help you resolve a problem. Read more about
Comments on this entry are closed.
Ramesh,
An unrelated question but specific to Ubuntu… I heard that there’s a directory copy installation available for Ubuntu. The last time I tried the normal install a couple of years back, it was scary. Any thoughts on this simple installation procedure.
May be you could post an article about that as well.
Cheers,
Ajith
PS: As such I am not a Linux user yet
I like having this in my .bashrc:
PS1=’\[\e[32m\]\t \h:\W \$ \[\e[m\]’
[[ $EUID == 0 ]] && PS1=’\[\e[31m\]\t \h:\W \$ \[\e[m\]’
(1) it colors the prompt green when I’m logged in as me, but when I have su’d into root, it goes red — a very useful distinction!
(2) it shows the current time in 24hr HH:MM:SS format due to the \t. There are lots of times when I run a command and walk away, and I would like an approximate idea of how long it actually took. (If I want “exact”, I’ll use the time command, but that’s not always needed)
I use this
C=$(tput setaf 6)
export PS1=’\[$C\]\u@\[$C\]\h:\[$C\]\w $ \[$RESET\]’
to know different colors supported by the terminal, use this
for i in {0..255}; do tput setab $i; echo -n ” “; done; tput setab 0; echo
I am using PS3 in my .bash_profile and it works like a charm but I am having an issue when the server is rebooted. One of the startup scripts login as “su -c oracle” and runs .bash_profile and booting of the server hangs because it is waiting for a prompt. How can I prevent that from hanging when server is rebooting from console? I prefer not to remove “PS3” from .bash_profile.