1. 47

Inspired by this recent submission, I’m interested how people set up their PS1 variables.

Here’s mine. I use bash.

(\u@droplet)-(\t)-(\w)\n(jobs:\j) $

(gustaf@droplet)-(14:11:19)-(~/prj/ProjectEuler/solved)
(jobs:1) $
  1.  

  2. 14

    $

    (I put the host in front only over ssh. Any other info goes in the terminal title)

    1. 6

      This. More specifically PS1=”\$ “ (that is “$ “ for users and “# “ for root). Colors disabled.

    2. 13

      I use the fish default. I grew of age in Unix before Linux, and only very slightly more recently than bash, so I have an old greybeard’s default for small prompts. Even more so, though, I have really given up on bikeshedding hyper-optimizing my operating environments, so I just roll with defaults almost all the time.

      1. 3

        Isn’t it unusual for a greybeard to use fish? I always thought of it as a more feature-packed and non-standard shell.

        1. 2

          Yeah, true, but I switched back a few years ago when I still had the energy for bikeshedding, and it’s just stuck. It’s less gross than the POSIX-y shells; although, were I to remain true to my greybeardism, I’d be using ksh88 – it’s what we had on the SGI machines BITD.

      2. 6

        Simply the bash default, with all colors disabled.

        1. 3

          I prefer coloured prompts as they let me see where my prompts are in seas of text back-history.

          What are your thoughts? Why do you prefer no prompt colours?

          1. 2

            Because then it doesn’t matter which color my background and fonts are; its always readable.

            1. 3

              Ooh yeah, I have particular problems with blue text on black. I’ve taken this a different direction by customising the default 16 colours to be a bit more sane for my screen and eyesight.

              I’m really surprised that few terminal utilities come with sane defaults. Perhaps all of the devs have much better monitors than mine :) As you mention fonts matter (higher weight/boldness makes low-colour contrast easier to handle).

        2. 6

          I use zsh, and mine is pretty basic.

          [woz@freebsd.local ~]
          >
          

          Username, hostname, current directory (chopped if it gets too long). It also shows the return code of the last command if it wasn’t 0, and will show version control information (branch name, etc.) if applicable.

          Maybe the only slightly unconventional thing is to use two lines.

          autoload -U colors && colors
          PROMPT="[%{$fg[green]%}%n%{$reset_color%}@%{$fg[red]%}%M%{$reset_color%} %{$fg[blue]%}%8~%{$reset_color%}] \
          \$(_git_prompt_info)%{$fg[red]%}%(?..(%?%))%{$reset_color%}
          $(echo '>') "
          

          For the record, I think using a framework for this kind of thing is kind of silly.

          1. 4
            ~/dotfiles master •
            ›
            ~/dotfiles master ×
            › 
            

            Depicts clean and dirty state of branch.

            1. 4

              Mine when normal user:

              |
              

              When root

              #
              

              I use PS1=$context| ' to set a key before prompt when working on project specific contexts to which I temporarily switch to.

              + () {
                (cd $2 && env -u HISTFILE DIRS="$DIRS $PWD" PS1="$1| " zsh -d -f)
              }
              

              For example, while working on another project, to switch to working on a book, I might exec the shell with the prompt as follows:

              | + book .
              book|
              

              When the temporary context switch is over, I simply ^D.

              All colors are disabled. I use the pipe (|) rather than $ as prompt to indicate that I have modified the shell environment of a specific machine, and my variables and functions are available. I used to set the HISTFILE also for project specific things, but found it not worth the trouble.

              1. 2

                What’s your motivation for using the pipe | instead of the traditional dollar sign $ for the prompt?

                Different but related: How the heck did we end up using dollar signs for our prompts? When you think about it, that’s pretty weird.

                1. 4

                  At one point in my life, I had to log into a new machines on a daily basis. The ‘$’ (bash) and ‘%’ (zsh) indicated that I have yet to customize that machine, and hence do not attempt things like git commit on those. The machines that I had customized and hence available for commits and other jobs (Solaris, Linux, FreeBSD etc.) I marked with ‘|’ i.e. ( PS1=”%(!.$1# .$1| )”) which was different from both $ and %, and occupied the least amount of space. I simply continued that practice.

                  A few others used ‘;’ which let them copy and paste terminal lines with a double click. In retrospect, that may have been a better choice.

                2. 3

                  My prompt normally looks like this:

                  thequux@peewee <~> 
                  [0]$ 
                  

                  This basic prompt has stayed almost exactly the same for 15 years (there was a brief time where the second line looked like : 0 ;, but I ended up finding that intrusive) . However, it has gotten a couple of subtle features:

                  If I am in a directory with a git repo, this changes to:

                  thequux@peewee <~/path/to/git-repo> (git:master)
                  [0]$ 
                  

                  There can be other tags that appear in the prompt as well: which python venv is activated, the name of the environment I’m chrooted into (if any), what version of Ruby is active through rvm, and any shell configuration files that have changed since the last time they were loaded.

                  There are also chevrons that appear on the left side to let me know I’m in a nested shell:

                  thequux@peewee <~> 
                  [0]$ zsh
                  thequux@peewee <~> 
                  >[0]$ zsh
                  thequux@peewee <~> 
                  >>[0]$ zsh
                  thequux@peewee <~> 
                  >>>[0]$ 
                  

                  Also, if I am root, the second line in the prompt turns red. It is all designed to be unobtrusive and only show me information when it’s relevant, but also, no matter how much information is being displayed, to give me as much space as possible to type my command line.

                  If anybody is interested, the complete configuration is at https://github.com/thequux/dotfiles/blob/master/conffiles/zshrc

                  1. 3

                    Depending on the machine:

                     hostname$
                     hostname%
                    

                    Or

                     ;
                    
                    1. 3

                      Mine is nice and simple. Using Bash, it shows date-time in white, then path in red. First line in my .bash_profile:

                      PS1="[\d \t] \e[0;31m\w $ \e[m "
                      

                      Example output:

                      [Mon Jun 17 11:52:27] ~/o19s/metric-plots $
                      

                      I have every new prompt in my shell print the current date/time, because I often run long jobs from the cli and its a nice little trick I have to check how long it ran.

                      1. 2
                        last_2/dirs_from_pwd [git_branch ●]
                        λ                       
                        

                        the dot is red when dirty. the lambda is red when $? is nonzero, since often a command won’t clearly result in an error message, but when the lambda turns red it’s a more consistent way for me to get failure feedback, for the commands that follow the convention, which is luckily still pretty much everything I use.

                        1. 2

                          I’m using Yori on Windows, so not directly applicable to Linux users, but:

                          YORIPROMPT=[$E$[32;1m`"git.exe" branch 2>NUL | ycut.exe -f 1 -d * -o 1`$E$[0;37m$B$$E$[36;1m%BuildType%$E$[0;37m] $P$$G_OR_ADMIN_G$
                          

                          Which looks like:

                          [<git branch in green>|<debug or release build in cyan>] c:\src>
                          
                          1. 2

                            Oh boy. All you guys have such fancy prompts. With all the fish and zsh and all. I have to admit that I basically just use whatever is default. So, on my Linux machine, I have

                            xfbs@Octavius:~$ echo $PS1
                            \u@\h:\w\$
                            

                            And on the Macs I use, I have

                            Remus:~ xfbs$ echo $PS1
                            \h:\W \u\$
                            

                            No multiline prompt. No colors. No plugins. No git branch or status. Nothing fancy at all.

                            1. 2
                              ✔ 2019-06-17 20:58:53
                              | george@marx ~ 
                              $
                              

                              The check mark becomes a “✘” if the previous command didn’t have a zero exit code. The | is just visually pleasing to me and helps align all the text. There are some colors as well. I name my computers after well-known or historical economic theorists.

                              1. 2

                                I use mksh. My shell used to be:

                                cwd$ 
                                

                                but after not remembering when I wrote a command it is now

                                hh:mm cwd$
                                

                                and of course it turns into a # for root. PS1 is:

                                PS1="\$(date +'%R') "'$(basename $(pwd))'"\$(if [[ \"\$(id -un)\" == \"root\" ]]; then echo \#; else print \$; fi) "
                                
                                1. 2

                                  Here’s my code that generates my prompt: https://github.com/kbd/setup/blob/master/HOME/bin/shell_sources/prompt.sh

                                  Full prompt with lots of state looks like:

                                  ⚡[venv][tmux:0:0]06/17@10:03:user@hostname:~/path[master][1&:1z]$:130
                                  

                                  The lightning bolt makes the prompt line stand out (though some terminals, like in vscode, don’t handle the double-width Unicode so I disable it). Then, the name of the virtualenv if you’re in one, tmux/screen state, the date/time, user@host, path, git status, background:suspended jobs, $, and the return code of the last command (if non-zero). There’s actually more, such as that the username changes color (yellow if su’d, red if root), and so on.

                                  Usually much of that isn’t necessary (like, user@host if you’re the login user on local), and iterm can show timestamps on each command, so typically a lot of that is elided to just:

                                  ⚡~/path$
                                  

                                  Finally, I have a ‘bare mode’ that is just$’ and the last command’s return code, cause ultimately (as u/WilhelmVonWeiner argues) everything else is unnecessary. Bare mode is good for screenshots.

                                  About that git status info ([master] above): at its most complex it could look like:

                                  [R >master ↑2↓2●2+2-2…2✖2⚑2]
                                  

                                  Which means: “currently rebasing, in a sub-repo, on master, 2 commits ahead and 2 behind of remote, 2 staged files, 2 changed files, 2 deleted files, 2 untracked files, 2 files in conflict and 2 stashes” (my ‘show fake data’ setting uses all 2s).

                                  That code is available at https://github.com/kbd/setup/blob/master/HOME/bin/repo

                                  1. 2

                                    It’s essentially been unchanged from what I set up with tcsh 15 years ago:

                                    [~]% true                                                          i:x270:14:32
                                    [~]% false                                                         i:x270:14:32
                                     1 [~]% cd /etc                                                    i:x270:14:32
                                    [/etc]% cd ~pack/gopher.vim/                                       i:x270:14:33
                                    [~pack/gopher.vim](master)%                                        i:x270:14:33
                                    

                                    Exit code, directory, and git branch on the left; the % switches to # for root.

                                    Hostname and time on the right. The i on the right switches to n for normal mode (although I don’t use the vi bindings much it’s useful sometimes).

                                    zsh config for it all:

                                    setopt promptsubst           # Expand parameters commands, and arithmetic in PROMPT
                                    
                                    autoload -Uz vcs_info
                                    zstyle ':vcs_info:*' enable git
                                    zstyle ':vcs_info:*' formats '(%b)'
                                    
                                    # Set mode variable for prompt
                                    function zle-line-init zle-keymap-select {
                                        mode="${${KEYMAP/vicmd/n}/(main|viins)/i}"
                                        zle reset-prompt
                                    }
                                    zle -N zle-line-init
                                    zle -N zle-keymap-select
                                    
                                    set_prompt() {
                                        vcs_info
                                    
                                        print -n "%(?..%S %? %s)"           # Exit code in "standout" if non-0.
                                        [[ $mode = n ]] && print -n "%S"    # Directory as "standout" in normal mode.
                                        print -n "[%~]${vcs_info_msg_0_}%#" # Directory and VCS info (if any).
                                        [[ $mode = n ]] && print -n "%s"    # End standout.
                                        print -n ' '
                                    }
                                    
                                    set_rprompt() {
                                        local host='%U%B%m%b%u'
                                        if [[ -n "${SSH_CLIENT}${SSH2_CLIENT}${SSH_CONNECTION}" ]]; then
                                            host="%F{red}${host}%f"
                                        fi
                                        print "${mode}:${host}:%T"
                                    }
                                    
                                    PROMPT=$'$(set_prompt)'
                                    RPROMPT=$'$(set_rprompt)'
                                    

                                    Complete config: https://github.com/arp242/dotfiles/tree/master/zsh

                                    1. 2
                                      » ~/prelude [2.5.5] (master) λ
                                      
                                      1. 2

                                        Here’s a pic of my prompt

                                        It’s available in zsh and bash… I’d love to refactor the zsh one to be as efficient as the bash one, but by zsh-fu is weak and I’m too lazy to bother figuring out why it doesn’t work as expected.

                                        1. 2
                                          PS1='${PWD##+(?)/} $ '
                                          

                                          My prompt shows only the basename of the current directory. The substitution above removes everything up to and including the final forward slash in PWD, except if there is only one slash in it:

                                          / $ cd home
                                          /home $ cd john
                                          john $ cd prj
                                          prj $
                                          

                                          I find this keeps the prompt short enough, while still helping me keep track of where I am.

                                          1. 2

                                            My fish shell looks like this:

                                            ➤                    done 00:43:39 [gb master]
                                            

                                            The arrow changes color depending on hostname and userid. To the right, the time when the previous command finished and a git branch (if possible).

                                            1. 2

                                              Just OpenBSD’s default: \h\$ (i.e. $HOSTNAME followed by a dollar or hash depending on whether or not I’m root), I haven’t had a need to complicate it.

                                              1. 2

                                                ;

                                                1. 2
                                                  export PS1="%(!.=> .-> )"
                                                  export RPS1="%1~"
                                                  ``` and I would show you what that looks like but lobsters collapses all the spaces between the two parts.
                                                  
                                                  I use zsh, without any extension framework, so it's pretty fast. The current directory name is on the right and an arrow is on the left (double stem for root).
                                                  
                                                  It's simple. Everything else I might want I can easily type, and I find that the slight effort in typing say `whoami` or `pwd` is worth more than a cluttered prompt (even if the clutter is useful). Most of the time I can remember what machine I'm on because I don't use many.
                                                  
                                                  1. 0

                                                    FYI: Lobsters doesn’t support GitHub’s special ``` code block syntax.

                                                    1. 1

                                                      That’s not the case, at least on my end.

                                                      I did indeed mess up the formatting by ending the backticks on the same line as the next paragraph, but it’s definitely monospaced.

                                                      On another note, I didn’t know it from Github, which I’ve never significantly used, but from Pandoc.

                                                      1. 1

                                                        Oh, it seems you’re right! I saw the weird formatting of your post and thought that Lobsters didn’t support the syntax. Thanks for clarifying!

                                                        1. 1

                                                          no worries!

                                                          I would fix it, but I can’t find an edit button, if there even is one.

                                                          1. 1

                                                            I think you can only edit your post for a few minutes after publishing it.

                                                            1. 1

                                                              It’s a bit longer than a few minutes but there is a time limit.

                                                  2. 2

                                                    I’ve got mine in my silly homemade homedir/dotfiles mgmt scripts: https://github.com/colindean/hejmo/blob/master/bash_profile/99_prompt.sh

                                                    [10:40:31 colin@alto-eject-roving ~/Source/work/project/dfp-services ]
                                                    ± (reword-logging %) $
                                                    

                                                    That second line is all __git_ps1 output except the $. When I’m SSH’d into a cluster, the hostname switches from hostname to the cluster name and gets highlighted in order to keep me from doing stupid things like wondering why my helper scripts aren’t available.

                                                    1. 2

                                                      I use

                                                      export PS1="[\\H] \\W \\$ "
                                                      

                                                      across all the machines I work on, that renders to something like

                                                      [bulbul] ~ $ 
                                                      

                                                      making it easy to quickly see where my command is going to by executed, when I have multiple terminals opened. Also I choose \\W over \\w, since most of the time I have a vague idea where I’m in the file system, and can easily check the details with pwd, but don’t have to run it excessively.

                                                      In eshell i just use $ though.

                                                      1. 2
                                                        ─────────────────────────────────────────────────────────────
                                                        23:59:59 username@hostname: ruby-2.5.0@gemsetname
                                                        master <git.committer.email@domain.com>
                                                        /current/directory
                                                        % 
                                                        

                                                        The horizontal line is added intentionally, to clearly delineate where the output of the previous command has ended. I also use colours for most of the components in there. Also prefixes the % with a (99) with the exit code of the last command, if any.

                                                        1. 2

                                                          [10:33:22 ~/src]$

                                                          1. 2

                                                            e.g. 13:28:40 user@host:~$ (screenshot)

                                                            In Bash: PS1='\D{%H:%M:%S} '${usercolor}'\u\[\e[m\]@'${hostcolor}'\h\[\e[m\]:\[\e[1;34m\]\w\[\e[m\]$(git_branch)$(hg_branch)\[\e[m\]\$ '

                                                            where usercolor and hostcolor are set based on the user and hostname so I can easily share the same .bashrc across multiple hosts, and git_branch and hg_branch are shell functions to look up the currently-checked-out branch when the CWD is in a git or mercurial repository. (I don’t regularly find myself dealing with hg repos anymore, so this is a reminder to myself that I should probably pull that one.)

                                                            This was reached basically by incremental addition to Debian’s default Bash PS1.

                                                            A few thoughts:

                                                            • I find color in the prompt extremely useful to separate the prompt from command output. The semantics I’ve assigned it are somewhat useful (e.g. if I import my user .bashrc as root, the username is red), but not nearly as much as having color at all. (Certain commands with brightly-colored output are annoying as they mitigate this benefit.)
                                                            • I also find SCM branch name very useful. I haven’t accidentally committed changes to the wrong branch in so long I can’t even remember the last time.
                                                            • Timestamping the prompt is a little bit useful. If I could somehow have it update the timestamp when I launch a command from that prompt, it would be more useful; otherwise I only have one piece of info (the end time, when the next prompt was printed) for the timing of commands.
                                                            • I print the full CWD. This gets annoying in deeply-nested hierarchies where it takes up a lot of horizontal space, but I get more annoyed by having it truncated (and it’s motivation to de-nest, I guess).
                                                            • I mentioned recoloring the user for root. Right now this is manual (i.e. . ~user/.bashrc is prominently in root‘s history). It’s possible to write a snippet for root‘s .bashrc to figure out who this instance of root is (basically, walk up the process tree until you find a su or sudo or something owned by somebody else) and autoimport their .bashrc, but I don’t really like the idea of either running all that logic in every interactive root shell, nor of automatically pulling in my .bashrc every time I login as root.
                                                            1. 1

                                                              If I could somehow have it update the timestamp when I launch a command from that prompt, it would be more useful; otherwise I only have one piece of info (the end time, when the next prompt was printed) for the timing of commands.

                                                              I started having zsh update the prompt every 15 seconds for similar reasons. I’m not sure if a similar facility is available in Bash, but it has proven nice. Maybe something like bash-preexec to echo the time just before running the command?

                                                            2. 2

                                                              Following the pattern:

                                                              ┌[$user][$machine-name][$branch-name][ssh?]:/current/folder
                                                              └$

                                                              For example:

                                                              ┌[rovanion][company78][master]:~/source/.files
                                                              └$

                                                              Defined here.

                                                                1. 2

                                                                  I use fish for my shell, and since it evaluates a function for the prompt each time (instead of PS1), this is what my fish_prompt function looks like:

                                                                  function fish_prompt --description 'Write out the prompt'
                                                                      set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g')
                                                                      set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g')
                                                                      set -l prompt_symbol ''
                                                                      switch "$USER"
                                                                          case root toor
                                                                              set prompt_symbol '#'
                                                                          case '*'
                                                                              set prompt_symbol '$'
                                                                      end
                                                                      printf "[%s@%s%s%s %s%s%s]%s "  $USER (set_color cyan) (prompt_hostname) (set_color normal) (set_color $fish_color_cwd) $pwd (set_color normal) $prompt_symbol
                                                                  end
                                                                  

                                                                  It’s pretty much the standard Bash prompt, for example:

                                                                  [user@host ~/dev/adventofcode-2017/day1]$

                                                                  The hostname is teal and the directory is a nice green. Everything else is white.

                                                                  1. 2

                                                                    I use what I’m sure was my OpenBSD default, but apparently I must’ve changed it (I’m now on Void Linux).

                                                                    export PS1="\\$ ". It’s $ unless I’m root, in which case it’s # .

                                                                    Anything else is unnecessary.

                                                                    1. 1

                                                                      I’m using fish. Left hand side is:

                                                                      waferbaby@(host name here) ~/ >

                                                                      Right-hand side is the current Git branch, if there is one.

                                                                      1. 1
                                                                        user@machine-name [~]
                                                                        $ 
                                                                        

                                                                        I can’t stand one line PS1.

                                                                        1. 1
                                                                          BOLD="\[$(tput bold)\]"
                                                                          RESET="\[$(tput sgr0)\]"
                                                                          PS1="${BOLD}[\u@\h \W]\$ ${RESET}"
                                                                          

                                                                          default+bold so it stands out in scrollback

                                                                          1. 1
                                                                            01:arrow/ (pr/4574) $ echo hi >> README.md 
                                                                            01:arrow/ (pr/4574✗) $ false
                                                                            01:arrow/ (pr/4574✗) ! 
                                                                            

                                                                            The git branch in green with a red dirty marker if the workspace is dirty. The $ transforms to a red ! if the previous command did not exit with 0. The path is truncated to the tip of the tree (top most directory).

                                                                            1. 1

                                                                              Default output:

                                                                              ╭──chris@cdk-rmbp-13 ~
                                                                              ╰→ 
                                                                              

                                                                              In a Git dir:

                                                                              ╭──chris@cdk-rmbp-13 ~/S/c/v3 (master=)
                                                                              ╰→ 
                                                                              

                                                                              The = after the branch name changes to include , , <> for “you should pull”, “you can push”, “you have conflicts”; != for “uncommitted changes”, ? for “untracked files”, and % for “stashed”.

                                                                              1. 1

                                                                                user~/a/b/r/eviatedPath:branch❯❯❯

                                                                                Fish

                                                                                1. 1
                                                                                  antek@succubus: ~/dev/android/craftbox_flutter master ⚡
                                                                                  $ ls                                                                   [21:54:18]
                                                                                  

                                                                                  I need git integration, and two lines because I like to see the directory I’m currently in, but at the same time I don’t want long directory names or long branch names to shorten the space for my commands. Also I need the name of the machine, because I use ssh quite often, and also I need to see current time in order to know how much time a long-running command took.

                                                                                  1. 1

                                                                                    looks like this

                                                                                    Schema: pwd:git:python-virtualenv[> if clean >> if dirty]

                                                                                    Underscores replace git and python-virtualenv if not in use. I use a ligature font that turns the >> into a single character.

                                                                                    This looks absolutely hellish, but here it is~

                                                                                    PROMPT=’%{$fg_bold[red]%}%~%{$fg_bold[green]%}:%{$fg_bold[yellow]%}$(parse_git_branch)%{$fg_bold[green]%}:%{$fg_bold[magenta]%}$(parse_virtualenv)%{$reset_color%}>$(parse_git_status) ’

                                                                                    1. 1

                                                                                      I use fish and have the path on the LPROMPT and version control/environment settings on RPROMPT, see here it looks like this:

                                                                                      ~/W/tlang »                                        ⏲default|1 ⑂ R26+|26 ⋐ tlang
                                                                                        |                                                  |       |     |   |    |
                                                                                       CPATH                                      CUR BRANCH       | CUR REV |    |
                                                                                                                                        BRANCH COUNT LATEST REV   |
                                                                                                                                                     APPENV PROFILE
                                                                                      

                                                                                      The idea is to put contextual information in the RPROMPT that shows the environment I’m working in, which in turn helps prevent mistakes (ie. I’m working off the wrong branch, I don’t see an available update, I’m working off the wrong environment).

                                                                                        1. 1

                                                                                          I use zsh, with the oh-my-zsh theme gnzh. I haven’t found it to have bad enough performance to both optimizing yet.

                                                                                          ╭─jennifer@godzilla.local ~/dev/ ‹9ff0af7*›

                                                                                          ╰─➤

                                                                                          1. 1

                                                                                            local machine as simple user

                                                                                            ychaouche#ychaouche-PC 13:59:33 /mnt/partage_local/VIDEOS/SCREENCASTS $
                                                                                            

                                                                                            Distant machine as root

                                                                                            root@messagerie[10.10.10.19] /usr/local/scripts/mail #
                                                                                            

                                                                                            Screenshots https://imgur.com/a/ZwbGMel

                                                                                            1. 1

                                                                                              I display the exit code from the previous command if it’s not 0, which is really nice. Other than that I have a timestamp and user- and hostname, and a shortened cwd.

                                                                                              $ this command does not exist
                                                                                              
                                                                                              Command 'this' not found, did you mean:
                                                                                              
                                                                                                command 'thin' from deb thin (1.7.2-1)
                                                                                              
                                                                                              Try: sudo apt install <deb name>
                                                                                              
                                                                                              127 09:14:17 runejuhl@managua:~/opt
                                                                                              $ ^C
                                                                                              130 09:14:24 runejuhl@managua:~/opt
                                                                                              $ echo omg
                                                                                              omg
                                                                                              09:14:28 runejuhl@managua:~/opt
                                                                                              $ ( echo omg && exit 2 )
                                                                                              omg
                                                                                              2 09:14:38 runejuhl@managua:~/opt
                                                                                              $ 
                                                                                              

                                                                                              Since I live and breathe git I once wrote some ugly oneliners to get the git status into PS1. It prints branch name and status for unknown, modified and added files. It uses colors too, so a modified file is a red 1M while an modified and added file is a green 1M:

                                                                                              09:15:08 runejuhl@managua:~/projects/clj-journal:master:v0.2.5-1:1??
                                                                                              $ git status
                                                                                              On branch master
                                                                                              Untracked files:
                                                                                                (use "git add <file>..." to include in what will be committed)
                                                                                              
                                                                                              	hs_err_pid28215.log
                                                                                              
                                                                                              nothing added to commit but untracked files present (use "git add" to track)
                                                                                              09:15:14 runejuhl@managua:~/projects/clj-journal:master:v0.2.5-1:1??
                                                                                              $ echo hello >> project.clj
                                                                                              09:15:24 runejuhl@managua:~/projects/clj-journal:master:v0.2.5-1:1M1??
                                                                                              $ git add project.clj
                                                                                              09:15:28 runejuhl@managua:~/projects/clj-journal:master:v0.2.5-1:1M1??
                                                                                              $ 
                                                                                              

                                                                                              The gist of it is this:

                                                                                              parse_git_branch() {
                                                                                                git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/:\1/'
                                                                                              }
                                                                                              
                                                                                              parse_git_status() {
                                                                                                git -c color.status=always status -s 2> /dev/null|sed -r 's/[ ]?(\x1b\[[0-9]{2}m)([^ ]+).*/\1\2\x1b\[m/'|sort -r|uniq -c|sed -r 's/[[:blank:]]+([0-9]+) (.*)/\1\2/'|tr -d '\n'|sed -r 's/(.*)/:\o033\[00m\1/'
                                                                                              }
                                                                                              
                                                                                              parse_git_tag() {
                                                                                                  (git describe --tags 2>/dev/null | sed -r 's/(.*)/:\1/') || :
                                                                                              }
                                                                                              
                                                                                              function print_git() {
                                                                                                branch="$(parse_git_branch)"
                                                                                                [[ -z $branch ]] && return
                                                                                              
                                                                                                echo -n "${branch}$(parse_git_tag)$(parse_git_status)"
                                                                                              }
                                                                                              
                                                                                              print_last_result() {
                                                                                                  l=$?
                                                                                                  [ $l -ne 0 ] && echo -en "\033[01;31m$l\033[00m "
                                                                                              }
                                                                                              
                                                                                              PS1='$(print_last_result)\t ${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00;33m\]$(print_git)\[\033[00m\]\n\$ '
                                                                                              
                                                                                              1. 1
                                                                                                1. 1

                                                                                                  People are going to hate this, but my prompt is multi-line, full width, and colored. It’s a little hard to copy-and-paste because it uses underlined text, so I’ll link a screenshot at the bottom.

                                                                                                  [wim@WDC-Mansa-Musa ~]                                   [13:10:08]
                                                                                                  ✔ ls foo
                                                                                                  foo
                                                                                                  [wim@WDC-Mansa-Musa ~]                                   [13:10:14]
                                                                                                  ✔ ls foo2
                                                                                                  ls: cannot access 'foo2': No such file or directory
                                                                                                  [wim@WDC-Mansa-Musa ~]                                   [13:10:20]
                                                                                                  ✕
                                                                                                  
                                                                                                  • At the front of the first line, there’s the straightforward [username@hostname current-directory]
                                                                                                  • At the end there’s a timestamp that can be used to determine when any command in the scrollback buffer finished executing.
                                                                                                  • The first line is always full-width in the terminal, an serves as an easy visual marker when scrolling through a ton of output if you want to find the beginning of the last command’s output, for example. I know you can pipe through less, but sometimes you get surprised by a large blurb of output, or forget to first redirect stderr to stdout, so it’s nice to have some comfort in your scrollback buffer.
                                                                                                  • The second line simply contains a green checkmark or a red cross indicating success or failure of the last command. This is the only colored element I’ve got.
                                                                                                  • Additionally, if a command runs for more than 30 seconds, my PS1 triggers a desktop notification. This is not really part of the visual prompt but it’s triggered through the prompt expansion so I thought I’d mention it. This is super-useful because I used to work on C++ code which takes FOREVER to compile, and whenever I started compiling I’d never sit around staring at the shell to wait for the result. It’s convenient to be notified as soon as the compilation finishes, otherwise I’d most likely only remember to check back after half an hour of working on something else (cough or watching YouTube cough).

                                                                                                  All of this is contained in my .bashrc (which does almost nothing else), and can be found here if you want to include any of this stuff into your own prompt.

                                                                                                  While I think a lot of this is personal preference, I can highly recommend the notification bit if you tend to have long-running commands.

                                                                                                  Screenshot with colors and underlines

                                                                                                  1. 1

                                                                                                    I use zsh, but I like to keep it simple:

                                                                                                    user@host:cwd%
                                                                                                    

                                                                                                    (Granted, this is exactly what I used in bash before zsh) This way, the part up to the % looks exactly like an scp/rsync path and I can just select and paste it if I want to use it as such.

                                                                                                    1. 1

                                                                                                      ZSH with Powerlevel9k

                                                                                                      1. 1

                                                                                                        I am using ZSH. My “main” (left) prompt is only a lambda. My side (right) prompt is a bit more “useful” (at least to me). Its implementation is here. Outside of a git repository, it’s just the current path. Inside a git repository, its: <root directory name>:<local path> (<branch colored in red or green>).

                                                                                                        For instance, my current side prompt is: freespec-tex:/journal (master)

                                                                                                        1. 1

                                                                                                          I have PS1="\h:\u \w> " in my .kshrc on OpenBSD which gives:

                                                                                                          port:fred ~>

                                                                                                          1. 1

                                                                                                            user on hostname in [~/foobar] on (master=)

                                                                                                            if ssh

                                                                                                            user@ssh on hostname in [~/foobar] on (master=)

                                                                                                              1. 1
                                                                                                                127 | sietse at dorothy in ~/clones/hg-clone-of-git-repo on default|master at 554 (default/master tip)  
                                                                                                                [I] 00:54:45$ 
                                                                                                                

                                                                                                                interesting elements:

                                                                                                                • 127 | is the exit code of the last command. It has let me notice when programs use the exit code to communicate the error type.

                                                                                                                • [I] is an indicator for readline’s vim mode: insert mode or normal mode? Comes with fish shell, I think.

                                                                                                                • a timestamp in the prompt is very nice to have, not just for estimating the duration of long commands, but also to reconstruct my day when I’m thinking ‘around when did I do this? Around when I ran command X’.

                                                                                                                • hg-prompt has an exceedingly nice syntax for optional text around an element that is not guaranteed to be present:

                                                                                                                      {optional text{tags}more optional text}
                                                                                                                  

                                                                                                                  This form will output the text and the expanded keyword only if the keyword successfully expands. This can be useful for displaying extra text only if it’s applicable:

                                                                                                                     "currently on {branch} {and at {bookmark}}"
                                                                                                                  

                                                                                                                Every templating language that deals with very small chunks of output should have this. Here’s how much more verbose a template language that doesn’t have this looks like: you repeat X once when printing it, and once-twice more when testing whether to print its surroundings. To avoid ’{rev} at {bookmark} with {tags}:turning into123 at with :`.

                                                                                                                    [templatealias]
                                                                                                                    # This is what the maybe_x templates do: if x exists, print x followed by a
                                                                                                                    # space. If it doesn't, print neither the x nor the space.
                                                                                                                    maybe_bookmarks = '{bookmarks}{ifeq(bookmarks, "", "", " ")}'
                                                                                                                    # in Steve Losh's notation, this could have been. '{{bookmarks} }'
                                                                                                                    # and then there would be no need for a templatealias to get compact notation.
                                                                                                                
                                                                                                                1. 1
                                                                                                                  /Users/pratul/Code/xxx (master ♺ )
                                                                                                                  >: 
                                                                                                                  

                                                                                                                  Slightly inspired by LOST! The “recycle” symbol means the current branch is clean. I replace it with a lightning bolt when the branch is dirty.

                                                                                                                  1. 1

                                                                                                                    I use bash and have a whole bunch of colours defined so this look rediculous:

                                                                                                                    PS1="$HC$FWHT[$FBLE\u$FWHT@$FCYN\h $FYEL\W$FWHT]$ $RS"
                                                                                                                    

                                                                                                                    It turns into this with white, bold blue, green, and yellow:

                                                                                                                    [dave@dsh-t560 ~]$
                                                                                                                    
                                                                                                                      1. 1

                                                                                                                        My entry is at the Janet Shell Gallery

                                                                                                                        1. 1

                                                                                                                          r00t_@ running powershell

                                                                                                                          1. 1

                                                                                                                            You use powershell?

                                                                                                                          2. 1
                                                                                                                            git_branch() {
                                                                                                                                branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
                                                                                                                                if [ "${#branch}" -ge "20" ]; then branch="...${branch:13:${#branch}}"; fi
                                                                                                                                if [ ! -z $branch ]; then echo "[$branch]"; else echo ""; fi
                                                                                                                            }
                                                                                                                            
                                                                                                                            export PS1="\u@\h \W\[\033[32m\] \$(git_branch)\[\033[00m\] ❗"
                                                                                                                            
                                                                                                                            1. 1
                                                                                                                              function parse_curr_git_branch_name() {
                                                                                                                                ref=$(git symbolic-ref HEAD 2> /dev/null) || return
                                                                                                                                echo " ("${ref#refs/heads/}")"
                                                                                                                              }
                                                                                                                              
                                                                                                                              function git_stash_count() {
                                                                                                                                  count=$(git stash list 2> /dev/null | wc -l | awk '{print $1}') || return
                                                                                                                                  if [[ $count -gt 0 ]]
                                                                                                                                  then
                                                                                                                                    echo "(⚡️ ${count})"
                                                                                                                                  fi
                                                                                                                              }
                                                                                                                              
                                                                                                                              function jobs_count() {
                                                                                                                                  count=$((jobs -s) | wc -l | awk '{print $1}') || return
                                                                                                                                  if [[ $count -gt 0 ]]
                                                                                                                                  then
                                                                                                                                      echo "(♺ ${count})"
                                                                                                                                  fi
                                                                                                                              }
                                                                                                                              
                                                                                                                              BOLD="%{$fg_bold[blue]%}"
                                                                                                                              RED="%{$fg[magenta]%}"
                                                                                                                              ALERT="%{$fg[yellow]%}"
                                                                                                                              RESET="%{$reset_color%}"
                                                                                                                              
                                                                                                                              function precmd() {
                                                                                                                                  PROMPT="$BOLD%m: %~$RESET$RED$(parse_curr_git_branch_name)$BOLD$ALERT$(git_stash_count)$RESET$BOLD$ALERT$(jobs_count)$RESET$BOLD%(!.#.✨) $RESET "
                                                                                                                              }
                                                                                                                              

                                                                                                                              Having a git stash count on the prompt is the only thing that keeps me from ending up with dozens of orphan stashes

                                                                                                                              1. 1

                                                                                                                                I wrote a small application that generates my shell-prompt, hence it is shell independent and the configuration looks basically like this: PROMPT="$(rusty-prompt $some_arg)"

                                                                                                                                https://github.com/klingtnet/dotfiles/blob/12090649b84304d6651874ada7b9664cfdc85a33/dots/.zshrc#L71 https://github.com/klingtnet/dotfiles/blob/master/dots/.bashrc#L17

                                                                                                                                Update:

                                                                                                                                This is how the prompt looks (without colors):

                                                                                                                                s1 alinz@m604 ~/code/klingt.net (master @0.4.0-15-gbeb73e9) (bat: 100%) (bat: AC) 1ms 41us 283ns
                                                                                                                                ƒ:
                                                                                                                                
                                                                                                                                1. 1

                                                                                                                                  zsh with prezto and pure prompt

                                                                                                                                  ~/Documents master*
                                                                                                                                  ›
                                                                                                                                  
                                                                                                                                  1. 1
                                                                                                                                    # If return code isn't 0, a nice red color and show it to me, please.
                                                                                                                                    # Then give me user@host. Then my current directory.
                                                                                                                                    # And finally, the history number of the command, and the $ or # symbol.
                                                                                                                                    export PS1='$(s=$?; [ $s == 0 ] || echo "\[\033[0;31m\]$s ")\[\033[0;34m\]\u@\H \[\033[0;32m\]\w\n\[\033[0;34m\]\!\[\033[0;00m\] \$ '
                                                                                                                                    
                                                                                                                                    # Have as many dots as our history number, and then some more.
                                                                                                                                    # Makes it look nice.
                                                                                                                                    export PS2='$(expr \! - 1 | tr '1234567890' '.').. '
                                                                                                                                    
                                                                                                                                      1. 1

                                                                                                                                        >

                                                                                                                                        1. 1

                                                                                                                                          In zsh:

                                                                                                                                          PS1="%~
                                                                                                                                          (%?) <`hostname -s`:`whoami`> $ "
                                                                                                                                          
                                                                                                                                          ~
                                                                                                                                          (0) <ono-sendai:kyle> $ 
                                                                                                                                          
                                                                                                                                          1. 1

                                                                                                                                            I’m running zsh with oh-my-zsh plus a few plugins for history navigation and syntax highlighting. The prompt itself looks like:

                                                                                                                                            ~/Code/cloud/google/terraform/deployments/prod/us-central1 master* 18s
                                                                                                                                            > 
                                                                                                                                            

                                                                                                                                            It is just the full path of the current directory, git branch/status and optionally time of the last running command (if its long enough (remote ssh, long-running process, etc)

                                                                                                                                            1. 1

                                                                                                                                              Mine is just $hostname%, like maple%

                                                                                                                                              1. 1

                                                                                                                                                Unique per-host hostname colour (automatically generated from the hostname text itself) and automatic window title updating. I copy and paste this as part of the .bashrc config I put on all of my servers, it’s really convenient.

                                                                                                                                                If you want to quickly test this: copy and paste it into a terminal running bash.

                                                                                                                                                colour_hostname=''
                                                                                                                                                colour_username=''
                                                                                                                                                colour_reset=''
                                                                                                                                                {
                                                                                                                                                        total=0
                                                                                                                                                        for num in $(hostname | od -An -t uC)
                                                                                                                                                        do
                                                                                                                                                                total=$((total + num))
                                                                                                                                                        done
                                                                                                                                                        total=$((total % 256))
                                                                                                                                                
                                                                                                                                                        colour_hostname='\033[38;5;${total}m'
                                                                                                                                                        [ "$(whoami)" == 'root' ] && colour_username='\033[31m' || colour_username='\033[32m'
                                                                                                                                                        colour_reset='\033[0m'
                                                                                                                                                }
                                                                                                                                                
                                                                                                                                                export PS1="\[\033]0;\u@\h \w\a\]\[${colour_username}\]\u\[${colour_reset}\]@\[${colour_hostname}\]\h\[${colour_reset}\] \w \$ "
                                                                                                                                                trap 'printf "\033]0;%s: %s %s\007" "$(whoami)@$(hostname)" "$PWD" "${BASH_COMMAND//[^[:print:]]/}"' DEBUG
                                                                                                                                                

                                                                                                                                                The window title updating code at the bottom is likely bash only. It makes sure that you can see the names of (long-running) commands in the window titles. Used it for a few years no wakkas.

                                                                                                                                                1. 1

                                                                                                                                                  I’m on zsh:

                                                                                                                                                  # 1 ptman@pumba:~ (git)-[master**]-
                                                                                                                                                  1013 %                                               # 2019-06-18 12:12:40 INS
                                                                                                                                                  
                                                                                                                                                  • 1 is exit code of previous command
                                                                                                                                                  • 1013 is history line number
                                                                                                                                                  • INS is vi mode

                                                                                                                                                  maybe I should move timestamp to previous line, but I think RPROMPT didn’t directly support that

                                                                                                                                                  1. 1

                                                                                                                                                    Mine is two lines so the input stays in the same location no matter how long the PWD path is.

                                                                                                                                                    qqbear@qqbear:~/Downloads

                                                                                                                                                    $ ls -al

                                                                                                                                                    1. 1
                                                                                                                                                      [08:51] [jwall@jwall-mb] (/Users/jwall)
                                                                                                                                                      $>
                                                                                                                                                      

                                                                                                                                                      I sacrifice some vertical real estate by using two lines. But I really don’t like losing horizontal space and I like the information I get.

                                                                                                                                                      1. 1

                                                                                                                                                        on zsh: export prompt="%n@%m:%~%# "

                                                                                                                                                        looks like this on my setup: laurent@DUVET:~%

                                                                                                                                                        Nice and simple but still has everything I need

                                                                                                                                                        1. 1

                                                                                                                                                          Just the path (\w) and when I ssh it’s host with path: [host] \w. Running bash with colors enabled.

                                                                                                                                                          1. 1

                                                                                                                                                            This simplistic version suits my needs of a traditional, yet useful, prompt:

                                                                                                                                                            +----------------------------------+
                                                                                                                                                            | user@host $ cd bin             ~ |
                                                                                                                                                            | user@host $ pwd            ~/bin |
                                                                                                                                                            | /home/user/bin                   |
                                                                                                                                                            | user@host $ cd /etc/zsh    ~/bin |
                                                                                                                                                            | user@host $ sudo -s     /etc/zsh |
                                                                                                                                                            | root@host # echo Loooooong line! |
                                                                                                                                                            | Loooooong line!                  |
                                                                                                                                                            +----------------------------------+
                                                                                                                                                            

                                                                                                                                                            Defined as:

                                                                                                                                                            autoload -U colors && colors
                                                                                                                                                            PROMPT_SYMBOL=$(print -P "%(!.#.$)")
                                                                                                                                                            if [[ "$PROMPT_SYMBOL" == '#' ]]; then
                                                                                                                                                                PROMPT_USERNAME="%F{red}%n%f"
                                                                                                                                                            else
                                                                                                                                                                PROMPT_USERNAME="%F{green}%n%f"
                                                                                                                                                            fi
                                                                                                                                                            PROMPT_HOSTNAME="%F{blue}%m%f"
                                                                                                                                                            PROMPT="${PROMPT_USERNAME}@${PROMPT_HOSTNAME} ${PROMPT_SYMBOL} "
                                                                                                                                                            RPROMPT="%~"
                                                                                                                                                            
                                                                                                                                                            1. 1

                                                                                                                                                              In bash:

                                                                                                                                                              __colour_prompt() {
                                                                                                                                                              	local c_red='\[\e[31m\]'
                                                                                                                                                              	local c_green='\[\e[32m\]'
                                                                                                                                                              	local c_lblue='\[\e[1;34m\]'
                                                                                                                                                              	local c_cyan='\[\e[1;36m\]'
                                                                                                                                                              	local c_clear='\[\e[0m\]'
                                                                                                                                                              	local lhs="${VIRTUAL_ENV:+(${c_green}$(basename ${VIRTUAL_ENV})${c_clear}) }${c_cyan}\h${c_clear} ${c_lblue}\W${c_clear}"
                                                                                                                                                              	local rhs
                                                                                                                                                              
                                                                                                                                                              	if [[ $UID == 0 ]]; then
                                                                                                                                                              		rhs="${c_red}"'\\$'"${c_clear}"
                                                                                                                                                              	else
                                                                                                                                                              		rhs="${c_green}"'\\$'"${c_clear}"
                                                                                                                                                              	fi
                                                                                                                                                              	if type __git_ps1 &>/dev/null; then
                                                                                                                                                              		__git_ps1 "$lhs" " $rhs "
                                                                                                                                                              	else
                                                                                                                                                              		PS1="$lhs $rhs "
                                                                                                                                                              	fi
                                                                                                                                                              }
                                                                                                                                                              
                                                                                                                                                              PROMPT_COMMAND='__colour_prompt'
                                                                                                                                                              

                                                                                                                                                              This adds a Python virtualenv name as a prefix if activated, and adds some git repo information as a suffix if in a git repo.

                                                                                                                                                              In zsh (this one is ancient - maybe 10-15 years old):

                                                                                                                                                              _BLUE=$'%{\e[1;34m%}'
                                                                                                                                                              _LBLUE=$'%{\e[1;36m%}'
                                                                                                                                                              _GREEN=$'%{\e[1;32m%}'
                                                                                                                                                              _RED=$'%{\e[1;31m%}'
                                                                                                                                                              _WHITE=$'%{\e[0m%}'
                                                                                                                                                              # The actual prompt is roughly a colourised version of:
                                                                                                                                                              #PS1='%n@%m:%~%# '
                                                                                                                                                              PS1="${_GREEN}%n${_WHITE}%B@%b${_RED}%m ${_BLUE}%5(~|%-1~/(..%)/%2~|%~) ${_LBLUE}%#${_WHITE} "
                                                                                                                                                              RPS1='%* %D'
                                                                                                                                                              

                                                                                                                                                              I always liked the bit of magic in the zsh one which shows a truncated version of the path so the prompt doesn’t get too long, but still gives you some context:

                                                                                                                                                              jamesog@euphrates ~ % cd /usr/local
                                                                                                                                                              jamesog@euphrates /usr/local % cd /usr/local/lib/zsh
                                                                                                                                                              jamesog@euphrates /usr/local/lib/zsh % cd 5.7.1
                                                                                                                                                              jamesog@euphrates /usr/(..)/zsh/5.7.1 % cd zsh/
                                                                                                                                                              jamesog@euphrates /usr/(..)/5.7.1/zsh %
                                                                                                                                                              
                                                                                                                                                              1. 1
                                                                                                                                                                : wiedi@maze ~ ; echo $PS1
                                                                                                                                                                : \[\e[0;32m\]\u\[\e[39m\]@\[\e[0;32m\]\h\[\e[39m\] \w \[\e[91;1m\]; \[\e[39m\]\[\e[0m\]
                                                                                                                                                                

                                                                                                                                                                The “:” and “;” make it easy to copy and paste for documentation.

                                                                                                                                                                1. 1

                                                                                                                                                                  I use Fish, and have a very simple prompt:

                                                                                                                                                                  function fish_prompt
                                                                                                                                                                      if [ $PWD = $HOME ]
                                                                                                                                                                          set directory '~'
                                                                                                                                                                      else
                                                                                                                                                                          set directory (basename $PWD)
                                                                                                                                                                      end
                                                                                                                                                                  
                                                                                                                                                                      set_color $fish_color_cwd
                                                                                                                                                                      echo -n $directory
                                                                                                                                                                      set_color normal
                                                                                                                                                                      echo -n " \$ "
                                                                                                                                                                  end
                                                                                                                                                                  
                                                                                                                                                                  1. 1

                                                                                                                                                                    PROMPT=%{%}%D%{%} %{%}%*%{%} %? %{%} %~ %{%} >

                                                                                                                                                                    Which turns into this:

                                                                                                                                                                    19-06-16 14:42:35 0 ~/oss_src/blend2d/asmjit >