loading...
Cover image for Customizing Your Shell Prompt for Productivity

Customizing Your Shell Prompt for Productivity

nikoheikkila profile image Niko Heikkilä Originally published at nikoheikkila.fi ・3 min read

To developers, the command line is a natural environment for daily work. It makes sense then to customize it to be as helpful as possible.

Try opening an uncustomized Bash shell on your machine and you will likely be greeted with a very unhelpful prompt (the text before your cursor) reading something like bash-5.0$. This only indicates you're running Bash shell version 5.0 which is the least useful information when opening the terminal.

What is useful enough information to include in the prompt then? I've gotten used to demanding the following information depending on the circumstances:

  • current working directory
  • current Git branch
  • current username if logged in to a remote machine or doing superuser stuff
  • system time if working in a full-screen mode
  • battery charge level if working on a laptop
  • state of the local project clone; eg. unstaged, modified, and deleted files or unpushed and unpulled commits
  • current application version from package.json if working with a Javascript project
  • current runtime version depending on the programming language

You can find suitable commands to print out this information and customize your shell startup file ~/.bashrc to include it but why keep reinventing the wheel?

Board the Starship!

Starship is a highly customizable cross-shell prompt created with Rust. It's a successor to the popular Spaceship theme for ZSH and the Spacefish theme for Fish. I've been using the latter for more than a year now, and I was mildly annoyed by its sometimes sluggish output. After all, navigating in the command line environment should be a blazing fast experience. Thanks to Rust, speed is no longer an issue with Starship. The project is not yet out of the beta but the foundation is very mature for daily use.

You can install Starship by downloading the binary file to your system or using Rust's package manager cargo. I would believe the maintainers will eventually add it to other popular package managers like APT and Homebrew as well. After installing, you should place this short snippet to your shell startup file.

# ~/.bashrc or ~/.zshrc
eval "$(starship init $0)"

# ~/.config/fish/config.fish
eval (starship init fish)
Enter fullscreen mode Exit fullscreen mode

This will load the Starship initialization code when you open a new shell session. If you want to peek the code before running it, remove the call to eval and run the expression inside parentheses.

Next, create a configuration file at ~/.config/starship.toml. Don't worry if you're not familiar with TOML syntax, it's very human-readable. Finally, start hacking with the documented configuration parameters and you might end up with something like this.

Starship Shell

Conclusion

With a few minutes of work, I've managed to squeeze out all the vital information from my environment. Now I can avoid typing pwd, git status, or node -v frequently and can focus being productive on my actual work.

You might argue this is a waste of time when you're switching machines regularly and will always fall back to the default Bash prompt. I used to think alike as well. However, unless you're a system administrator from the early 2000s with no better workflow than SSH'ing to servers, chances are you will be working in your local environment for 95% of the time. There's no need to discard productivity customization due to this 5%. The return on investment in doing this is huge.

I bet you have some nice customizations there. Share them in the comments!

Posted on by:

nikoheikkila profile

Niko Heikkilä

@nikoheikkila

Software craftsman with a strong passion for open source software and continuous improvement.

Discussion

pic
Editor guide
 

Fun-but-slightly-fragile fact: if you are SSH-ing to servers that don't reset the prompt, you can send your own by setting up ssh to send over your PS1 variable (the variable that contains the prompt specification for bash), and setting up the sshd to accept it.

In your /etc/ssh/sshd_config:

AcceptEnv PS1

And then:

ssh -o SendEnv=PS1 myserver.example.com

Or add it to your ~/.ssh/config file:

SendEnv PS1

(If you customise the other types of prompt as well, those are PS2, 3, and 4, and you can send those as well: just separate with whitespace. And check man ssh_config for more info.)

 

I was not aware of this feature. Quite cool, although it smells of remote code execution and therefore maybe not many SSH targets have this enabled by default?

 

Well, at that point you're already doing remote code execution manually by logging in. But, yes, the default is to not accept any environment variables, so it would only work if you already have the ability to alter the SSH daemon configuration. If you have that, you already have sufficient permissions to do almost anything to the machine anyway.

I guess a use case would be if you were deploying an OS image and didn't want to bake your prompt into it, but still wanted it available.

 

This is really really good and would like to apply this to my terminal in Linux. However I have little to no experience in customizing my terminal. I always stick to bash because I'm a little bit scared to touch it if anything goes wrong lol..

Hope you can give some tips for the downright beginners =) this looks too good. =)

 

Then you're delighted to know that Starship is basically zero-configuration prompt. Install it and it's usable from the get go. Of course, you can customize it with the TOML file mentioned.

I think installation instructions here are pretty good. If you have Mac, you can just use Homebrew to fetch it. Hit me with a DM, if you get stuck.

 

Very nice. I assume this will work in WSL too?

 

Correct. This only affects the shell so you can choose the platform to your liking.