Image of the glider from the Game of Life by John Conway
Skip to content

My ZSH Prompt

Lately, I've been plagued with getting my zsh prompt exactly the way I want. I've been using the clint theme bundled with zsh, but it's multiline prompt, and poor color choice started getting to me. So, I figured I'd change it and start with something simple, maybe mimicking bash a little, and slowly building out from there. The result, thus far, I'm pleased with. It's a basic bash-like prompt, showing the username, hostname, current working directory and current history number. What isn't showing, but will if needed, is the returned exit code on failure. Here's a demo of the prompt in action:

aaron@kratos:~ 262 % ls -ld tmp 
drwxrwxr-x 2 aaron root 4096 2008-01-30 13:22 tmp
aaron@kratos:~ 263 % rm -rf tmp
aaron@kratos:~ 264 % ls -ld tmp
ls: tmp: No such file or directory
aaron@kratos:~[2] 265 % echo $?
2
aaron@kratos:~ 266 %

Nice. Only showing the exit code, when there's a failure, otherwise, keep it hidden. What I currently can't figure out, but will, is showing only when I'm behind a screen session. So far, the PS1 variable is as follows:

aaron@kratos:~ 266 % echo $PS1
%n@%m:%~%(?..[%?]) %h %#
%n - username
%m - hostame up to the first dot
%~ - current working directory
%(?..%?) - testing for failure on exit code
%? - the exit code
%h - history number
%# - % if unprivileged, # if privileged

The tricky part for me, was getting the syntax for testing the exit code. The syntax is %(x.true-string.false-string), where 'x' is some arbitrary testing condition, in this case, '?' for exit codes. After the first dot, if the test passes, show true-string, if it fails, show false-string after the second dot. So, in my case, I'm returning an empty string on a returned 0 exit code, and the failed exit code on false (in brackets). Now, to figure that out with screen sessions.

What do you think? If you're a zsh user, I'd be interested in your PS1 variable.

{ 15 } Comments

  1. Thom May using Firefox 3.0b3pre on GNU/Linux 64 bits | January 31, 2008 at 8:02 am | Permalink

    if [[ -n $SSH_CLIENT || -n $REMOTEHOST ]] then
    PS1=': ${CHROOT}%T %(5~|.../%2c|%~) %# '
    RPROMPT=%n@%m
    else
    PS1=': ${CHROOT}%T %(5~|.../%2c|%~) %# '
    fi

  2. Tuxero using Firefox 2.0.0.11 on Ubuntu | January 31, 2008 at 8:17 am | Permalink

    What is ZSH?
    This is the first time I hear about it.
    Cheers mate!

  3. Smarter using Konqueror 3.5 on GNU/Linux | January 31, 2008 at 9:12 am | Permalink

    [smarter@fenny ~/Builds/revu/extremetuxracer]% echo $PS1
    %{$reset_color$bold_color$fg[green]%}[%{$reset_color$reset_color$fg[green]%}%n%{$reset_color$bold_color$fg[green]%}@%{$reset_color$reset_color$fg[green]%}%m%{$reset_color$bold_color$fg[green]%} %{$reset_color$reset_color$fg[cyan]%}%~%{$reset_color$bold_color$fg[green]%}]%{$reset_color$reset_color$fg[green]%}%# %{$reset_color$reset_color%}
    Clean and green (:

  4. eddie using Firefox 2.0.0.11 on Ubuntu | January 31, 2008 at 10:07 am | Permalink

    What is ZSH?

    cool dude. We are heading to a momentum when everybody can handle xorg.conf or grub but doesn't know what bash is.

    computer illiterates ftw!

    PS: copying your $PS1 to my ~/.bashrc at light speed

  5. Scott Robertson using Firefox 2.0.0.2 on SuSE | January 31, 2008 at 11:45 am | Permalink

    PROMPT=$'%(!.%{\e[1;31m%}.%{\e[1;32m%})%n@%{\e[1;34m%}%m:%{\e[1;31m%}%1~%{\e[1;00m%}%(!.#.$)'
    RPROMPT='%(?..%?)'

    name@host:(last element of pwd)$
    At far right is the exit code if not 0.
    Colors make it a bit hard to read.

  6. Seth using Epiphany 2.20 on Debian GNU/Linux | January 31, 2008 at 12:33 pm | Permalink

    I can respect that you don't like multi-line prompts (sometimes they can really get in the way, or make the terminal look *super* busy (the clint theme is three (!) lines)). In spite of that, here's a quick note about the bad default colors:

    prompt clint blue cyan white yellow white
    prompt -h clint

    Regardless, nice writeup of a simple and elegant prompt.

  7. Glenn using Firefox 2.0.0.11 on Ubuntu | January 31, 2008 at 2:51 pm | Permalink

    My PS1 prompt is pretty basic:
    PS1=%B%m%b >

    but what I really like is the right justified prompt which is where I display the current directory...

    RPROMPT=%~

  8. Hobbsee using Firefox 3.0b3pre on GNU/Linux | February 1, 2008 at 2:50 am | Permalink

    Thanks thom! I'd been wondering about a different remote prompt! Mine now is:

    if test `whoami` != "root"
    then
    PS1="${fg_light_cyan}%B%n@%m:${fg_light_blue}%~${fg_light_gray}%#%b "
    else
    PS1="${fg_red}%B%n@%m:${fg_red}%~${fg_light_gray}%#%b "
    fi
    RPROMPT="${fg_cyan}%t${fg_no_colour}"

  9. Anonymous bin Ich using Firefox 3.0b5 on GNU/Linux | April 4, 2008 at 10:02 am | Permalink

    ___________________

    PROMPT=$'%(?..%{\e[41;38m%}%B-%?-%b%{\e[0m%} )%(1j.%{\e[01;33m%}[%j] .)%{\e[01;32m%}%m%{\e[0m%} %{\e[01;36m%}%2~%{\e[0m%} %B%#%b '
    RPROMPT=$'%{\e[00;07m%}%(?..$exitstuff)% %{\e[0m%} %T'

    # Taken and modified from "atom's .zshrc" public release v0.109 - http://smasher.org/zsh/
    precmd () {
    local exitstatus="${?}"
    if [[ ${exitstatus} -ge 128 && $exitstatus -le (127+${#signals}) ]]; then
    # Last process was killed by a signal. Find out what it was from
    # the $signals environment variable.
    exitstuff="${signals[${exitstatus}-127]}"
    else
    unset exitstuff
    fi
    }

    ___________________
    The function here tells you the name of the interrupt, which I like :)
    Also, RPROMPT tells the time in reverse video, so no problem while testing different themes etc. Although I am planning to switch it to the left so that copy-pasting can become easier :)

  10. mjg using Firefox 3.0 on Windows XP | May 30, 2008 at 1:51 pm | Permalink

    this is in my .zshrc:

    local smiley="%(?,%{$fg[green]%}:%)%{$reset_color%},%{$fg[red]%}:(%{$reset_color%})"
    PROMPT=$'%{\e[0;36m%}%B[%b%{\e[0m%}%B%n%b%{\e[0;36m%}%B@%b%{\e[0m%}%B%m%b%{\e[0;36m%}%B]%b%{\e[0;36m%}%B[%b%{\e[0m%}%B${smiley}%b%{\e[0;36m%}%B]%b%{\e[0m%}%B%#%b

    looks like this:

    [user@host][:)] % cd sh
    [user@host][:)] % ls foo
    ls: cannot access foo: No such file or directory
    [user@host][:(] %

    It will show a green smiley if the last command finished successfully, or a red frowney if it did not.

  11. Redd Vinylene using Firefox 3.0.4 on Windows XP | December 7, 2008 at 4:13 am | Permalink

    Hello Aaron! What you think of this?

    -

    if [[ `whoami` = root ]] then

    a1="%{$fg_bold[red]%}"

    a2="%{$fg_no_bold[red]%}"

    else

    a1="%{$fg_bold[white]%}"

    a2="%{$fg_no_bold[white]%}"

    fi

    PROMPT="$a1(%n@%m)$a2(%D{%d/%m}+%D{%H:%M})"$'\n'

    PROMPT+="$a2(%~) %{$reset_color%}"

    -

    Do let me know!

  12. James using Safari 525.27.1 on Mac OS | January 6, 2009 at 5:42 pm | Permalink

    # Git branch
    function __prompt_git() {
    local git_dir ref br top;
    git_dir=$(git rev-parse --git-dir 2> /dev/null) || return
    ref=$(git symbolic-ref HEAD 2> /dev/null) || return
    br=${ref#refs/heads/}
    top=$(cat $git_dir/patches/$br/current 2>/dev/null) && top="/$top"
    echo "($br$top)"
    }

    # Colour stuff
    autoload colors zsh/terminfo
    if [[ "$terminfo[colors]" -ge 8 ]]; then
    colors
    fi
    for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do
    eval PR_$color='%{$terminfo[bold]$fg[${(L)color}]%}'
    eval PR_LIGHT_$color='%{$fg[${(L)color}]%}'
    (( count = $count + 1 ))
    done
    PR_NO_COLOR="%{$terminfo[sgr0]%}"

    # Environment variables
    PS1="$PR_LIGHT_BLUE%m$PR_NO_COLOR:$PR_LIGHT_WHITE%2c$PR_NO_COLOR %n%(!.#.$) "
    RPS1="$PR_LIGHT_RED$(__prompt_git)$PR_NO_COLOR $PR_LIGHT_YELLOW%D{%H:%M}$PR_NO_COLOR !%h"

    Lovely little prompt. Looks kinda like…

    osx:~ james$ (master) 00:38 !61

    …but with lots of pretty colours! :o

    I'm mainly posting because I want a Mac with Safari on the comment list!

  13. Erus_Iluvatar using Minefield 3.7a1pre on GNU/Linux 64 bits | January 8, 2010 at 10:37 am | Permalink

    PS1="%(!.#.$) "
    RPROMPT="%(?..%F{red}!%?!%F%F{white}:)%~%(1j.:%j.)"

    Simple and powerfull.

  14. Brianskywalker using Links on Debian GNU/Linux | April 13, 2010 at 12:47 am | Permalink

    > cd /usr/share/doc/zsh/
    >

    local pscolor="%B%(?,%F{green},%F{red})"
    PS1="${pscolor}> %f%b"
    PS2="${pscolor}> %f%b"
    RPROMPT="(%!%) %T"

    A very simple ascii art fish, used as a ps1. The eye is actually the pwd, and the fish turns red when the last command returns an error. I also have a right-aligned prompt with the history event number and time.

    This is somewhat novel but very useful.

  15. Aaron using Google Chrome 5.0.307.11 on Mac OS | April 13, 2010 at 7:54 am | Permalink

    @Brianskywalker I can't reproduce your prompt. I just get a series of double quotes. On the other hand, I like adding an ASCII fish to the prompt. I need more of a playful prompt.

{ 1 } Trackback

  1. My ZSH Prompt | January 31, 2008 at 9:22 am | Permalink

    [...] unknown wrote an interesting post today onHere’s a quick excerptaaron@kratos:~ 262 % ls -ld tmp drwxrwxr-x 2 aaron root 4096 2008-01-30 13:22 tmp aaron@kratos:~ 263 % rm -rf tmp aaron@kratos:~ 264 % ls -ld tmp ls: tmp: No such file or directory aaron@kratos:~[2] 265 % echo $? 2 aaron@kratos:~ 266 % … [...]

Post a Comment

Your email is never published nor shared.

Switch to our mobile site