Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Useful Shell Prompt (2020) (solovyov.net)
56 points by webmaven on April 2, 2022 | hide | past | favorite | 45 comments


The starship prompt is astoundingly good value-for-effort. https://starship.rs/

It's very feature-rich, showing suitable context for a variety of tools, and can be customised if the defaults don't provide the information you're after.


Starship.rs is great. It has the red prompt feature mentioned in TFA by default. And it’s fast. And means I can easily have the same prompt in bash and zsh, on macos and Linux.


The website says it’s feature rich. Do they have a list of features?

Is there any reason why a prompt is written in rust?


I'd take a look at the headers under the configuration options. (e.g. AWS, Git, Python, Status). https://starship.rs/config/

> Is there any reason why a prompt is written in rust?

The prompt program supports a bunch of different shells. I imagine that's going to be easier to maintain in Rust than in bash.


Shell is kinda awful to write, so people started using python, which is too slow for this (just the startup times...), so they moved to rust


The question “Why isn’t this written in Rust” is ridiculous and a distraction but “why is […]” is even moreso.


Debian dash can be compiled with editing modes for vi and emacs.

There is great love from many for more capable shells, but the flaws of these are visible to all; "man bash" plainly states that it's "too big and too slow."

Minimal dash compiles to under 80k for i686, and Arch Linux asserts it to be 4x faster than bash.

It is with some regret that we did not adopt a shell syntax that could be cleanly LR-parsed with yacc and lex, but that was the fault of the founders.

Bill Joy has admitted his own flaws in the C shell, and Brian Kernigan should have torn that code apart, replacing it with awk syntax upon a shell. In a parallel world, it would have been a much more capable shell.

As things stand, we must struggle with the Algol of our forbearers, that requires an extremely advanced parser, and to make due with what is permitted to us.

https://m.youtube.com/watch?v=fiJR4_059HA


The author of the musl C library has this to say about the POSIX shell:

"I am a strong believer that Bourne-derived languages are extremely bad, on the same order of badness as Perl, for programming, and consider programming sh for any purpose other than as a super-portable, lowest-common-denominator platform for build or bootstrap scripts and the like, as an extremely misguided endeavor."

https://www.etalabs.net/sh_tricks.html


The basic unit on which shell scripts build is external commands. If what you want to do is to tie a few together, it is by far the best tool. For the type of programming problem where you need data structures it is indeed awful. But things like Python are really quite poor when it comes to executing external commands. You either need a dozen lines for each external command or things are done in a crap way with commands running synchronously when they don't need to be. With many real languages, people use a `system()` function that is running sh every time along with evaluation because the alternative is fork/exec/wait etc.

Many of those sh tricks you link to are better even in the common ksh/bash/zsh subset than in pure POSIX.


My point is that the shell would be a much better tool if the language could be expressed with a simple, LR-parsed yacc grammar.

Because the shell needs such an advanced parser, it shows that the language is full of ambiguity and pitfalls.

The slides for the parent presentation have this gem:

Quiz: Which is the command that outputs \\ ?

1 echo "\\\"

2 echo "\\\\"

3 echo "\\\\\\"

The language should be clearer, and less ambiguous.


> super-portable

what else may come in mind to use?


If you're running zsh, I suggest using powerlevel10k[0]. It is stupid fast, and extremely customisable.

[0] https://github.com/romkatv/powerlevel10k


P10k is one of those revelations that feels “next generation”. Trying to back to anything else is very painful for me, even things that are supposed to be “fast” like starship.


For p10k users, adding extra info to your prompt is really easy. Here's my epoch-seconds display:

    function prompt_epoch() {
      MYEPOCH=$(/bin/date +%s | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')
      p10k segment -f 66 -t ${MYEPOCH}
    }
It looks like this in action:

https://i.imgur.com/0IT5zXi.png


In the spirit of p10k speed, you can perform that task without forks:

    $ zmodload -F zsh/datetime p:EPOCHSECONDS
    $ printf "%'d" $EPOCHSECONDS
    1,648,943,504


Do you know how to do that printf within a zsh variable? i.e. here:

    function prompt_epoch() {
      p10k segment -f 66 -t ${MYEPOCH} <-- replace MYEPOCH with EPOCHSECONDS but with commas?
    }
EDIT: printf can assign output to a variable using -v. Therefore my function can be rewritten as:

    function prompt_epoch() {
      printf -v COMMA_EPOCH "%'d" ${EPOCHSECONDS}
      p10k segment -f 66 -t ${COMMA_EPOCH}
    }


Nice, thank you!


Your imgur link isn't working for me. I'm getting an "oops we can't find the image".



I've been using Pure for a handful of years now. I just want pwd, git and vi status, and prompt on its own line, and it does it all. Available on both zsh and fish, I seem to remember a Powershell port as well, if that's your style.


I used to use Pure a couple of years ago. I found it had some weird bugs that were really annoying, not very reproducible and my shell knowledge was not nearly good enough to debug it. I think especially the async stuff was very error-prone. Maybe that’s changed now.

Powerlevel10k is very customisable, faster, can be configured to function exactly like Pure out of the box and in my experience, more reliable.

I would recommend powerlevel10k over Pure any day. But it’s just an anecdotal datapoint.


Yeah, maybe. I'm just really lazy.

Edit: Well that was easier than expected, their initial setup daemon is pretty well made, and the "instant prompt" is pretty cool. Feels snappy.


I used to use a colored indicator for the exit status, but a while ago I switched to a multiline prompt:

  (last command returned 1.)
  » 
Or, if the previous command terminates due to a signal:

  (last command got signal SIGTERM.)
  » 
Color doesn't survive c/p in practically any medium, and the exit status is useful when showing things to co-workers.

The bigger hint also highlights when a command unexpectedly errors (e.g., while emitting text to the effect of "Success!") and the opposite case, where a command appears to fail and exits with success anyways.


I've been doing this a long time in 4NT.

    PROMPT=[$r][ $P ][ $t ]$_$g
Appearance is along these lines:

    [0][ C:\bin\4nt ][ 15:30:07 ]
    >
Super useful. It's good to get advance warning of strange exit codes when trying things out interactively with a view to using them in some automated process. The exit code also shows the exception type if the process terminates due to an exception - alway handy to know.

I also like always having the same amount of space for the command, visually, regardless of the working folder.


Oh, that's very nice. By any chance have you posted your dotfiles somewhere so that I can steal it?


https://github.com/thanatos/dotfiles/blob/master/shell/zsh/p...

I've tried to highlight roughly the relevant bits.

The basics of it is that we lazy-load an associative array between exit statuses that are signals and their prettified names. (Which we more or less build by querying Python, to get at what's, essentially, defined in signal.h.)

Once we have that assoc. array, when we get a non-zero exit, we see if it's in the array. If it is, look up the pretty name, print message. If not, just print message with raw exit status. Red & bold so it shows up. (Should probably also use bright red, too. But my work laptop is macOS, & so it's iTerm2, and iTerm2 interprets "bold" to mean "bright & bold".)

I also use zsh, which is able to be considerably more expressive in what it can accomplish in a PS1 than bash can. Note that the syntax,

  ${+VAR}
which appears in there is zsh-specific. It can be done in bash, but it isn't as neat. I don't recall if bash has associative arrays or just arrays, too…


I've been using pure theme for a few years and absolutely love it. It shows me everything I need, but doesn't feel cluttered.

It uses 2 lines, which is actually really nice. It gives space to show where you are and git status/branch, while still allowing you to write long commands.

https://github.com/sindresorhus/pure


I don't get why everyone wants git status on every prompt. It feels more of a distraction than necessity just to make it look prettier for screenshot purposes.

Most of the time I'm within a repo directory, I don't care in which branch or state it's in as I have other apps to take care of that and there are better info to be had like cwd, who you're, host name, exit code, time and time last command took for a prompt.


I admit that having the branch name always there is overkill, but having it display your rebase status or flag when there are uncommitted changes is genuinely useful.


If you multitask between several projects, it becomes very useful very fast.


Also it’s useful to see what branch you were on when you ran a particular command, as you scroll up through the commands and outputs you ran previously.


I use it all the time. When working in GCP, I could really have used a prompt that told me current gcp project.

But sure, if you are not using hit in your shell, then you don’t need fit in your shell.


I'm a huge, huge fan of writing your own prompt. I've had too many people not actually understand what was being displayed to them by their latest and prettiest version of their prompt and have to walk them through it. The folks posting here are unlikely to be in this camp, but I've had people with their full working directory in the prompt running `pwd`. If you're not going to use the information from the prompt, don't include it.

A big problem I had at a former employer was that `git status` would take 2+ seconds to return (for various reasons) and the default oh-my-zsh prompt would parse the results of `git status` to display the repository. People thought it was normal to wait more than half a second to get a prompt back! I lost trust in 3rd party prompts from that experience, and while I have sunk at least a few hours into my own prompt, I know exactly how it works, what calls it's making, and where things go wrong (when they do).


Here is a useful prompt:

PS1='$?:[$(date +%m%d:%H%M%S)]:\h:\w\$ '

you have

- termination status of the last command

- date and time the prompt was last redrawn in [MMDD:HHMMSS] form.

- host, working dir, prompt character #-root $-user


Related to this, something I did 10 years ago and started seeing more often (especially in git-bash!) is to have

* a newline before your current prompt

* a newline after all your context and right before your "$ "

This helped me tremendously with scanning terminal output for years. More default $PS1's should do this.


fish already does this in most of the included prompt themes :)


I’ve started putting more things in tmux status, down and to the right. Repo/cwd, branch, and commits beyond master are pretty handy things to see. They change a lot depending on which window I’m in.

It would be cool in tmux to have a shortcut to a quick popup showing more git info (status, log origin.., which of the patches have pull requests.) You could do that stuff with a shell command or a vim plugin, but tmux is the common thread, so adding it there seems a better place for it. Kind of like a sticky window in a tiling wm (mod space in i3) but in the terminal.


So, basically, what fish gives out of the box :)


If you love this, you should try ohmyzsh.

The default prompt with the status arrow and directory are awesome. You can also extend ZSH functionality with plugins. I can't live without git and timer plugins anymore.


I personally prefer prezto to omz because omz feels noticeably sluggish on my machines, whereas you can use prezto with powerlevel10k (built-in, just need to switch the theme in the config) and it’s lightning fast. Can’t use anything else after getting used to how fast it is.



I set up a status based prompt too - but in bash instead


Can the red arrow be done in Bash?


Install https://starship.rs it works with bash and zsh, and many others shells. And you get the red arrow for failed commands out of the box. No extra config required.


Wow, that's the only useful fancy prompt I've ever seen over \w\$




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: