Perhaps the highlight of this week’s at-work updates was my first PR as a professional engineer (!!!). A senior member of my team was guiding me through our GitHub process and noticed that I was having trouble remembering my branch name, which wasn’t displayed in my terminal window. She shared a bash script that I could use to easily see which branch I was on without having to use a git command:
if
[ -f ~/.git-completion.bash ];
then . ~/.git-completion.bash;
fi[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}export CLICOLOR=1
export LSCOLORS=ExFxBxDxCxegedabagacad
alias ls='ls -GFh'
export PS1="\[\e[1;32m\]\w\[\e[1;36m\]\$(parse_git_branch)\[\e[1;35m\]$\[\e[0m\] "
That’s so helpful! …but this is a bash script and I use zsh, so it’s not quite so easy to drop into my run commands. I didn’t remember choosing to use zsh and I certainly couldn’t say why anyone would choose one over the other. So I decided to do a bit more research and see if I could sort this out.
What are Bash and Zsh?
The terms bash and zsh refer to command line shells. These tools provide an interface to our Unix system — the organization of files and programs that operate a computer. If you have any experience using your computer’s terminal or command line, you’ve likely used one of these shells to navigate to files and programs. What you may not have realized is that you may have executed shell scripts as well — logic built into a shell’s configuration that can help automate a process, like the script my coworker shared with me.
Bash and zsh aren’t the only shells out there — in fact they’re not even the two most popular (bash is a solid #1, but zsh is mixed in with a few others in the rankings). The first Unix shell was created in 1971 by Ken Thompson and, naturally, would go on to be known as the Thompson shell. If, like me, you’re more of a web developer than a system administrator, using the Thompson shell probably wouldn’t present you with too many issues. It was great at navigating and executing commands, but where it fell short was scripting.
Solving this problem was the goal of Stephen Bourne when he released his own shell in 1977. In addition to supporting scripts, the Bourne shell introduced variables, control flow, and loops to the command line. But his shell was the property of Bell Labs and not accessible to a majority of programmers, which didn’t sit well with Richard Stallman and the folks at GNU. The GNU operating system was developed with the idea of access (you can read more about this in a previous blog post of mine) and sought to iterate on many of the existing, privately-owned Unix features. Brian Fox was tasked with developing the shell, and so the Bourne shell was born again. The shell was aptly named bash, which stands for born-again shell.
What about zsh?
Bash would go on to become ubiquitous in Unix and Linux systems while a few other shells, such as csh, fish, and ksh, competed for attention amongst users with specific needs and wants. Zsh was no different: developed in 1990 by Paul Falstad, the Z-shell was an iteration on ksh (Korn shell) that included enhancements of many types, notably in the command-line editor, options for customising its behaviour, filename globbing, features to make C-shell (csh) users feel more at home and extra features drawn from tcsh (another `custom’ shell). (zsh.sourceforge.net)
We can use parts of this description to help understand what zsh brings to the table and why some users prefer it over bash and other command line shells.
Command-Line Editor
One exciting zsh feature is the ability to auto-complete in the command line. For example, start typing out a path, then press tab to have the shell run logic to complete a filename or provide a collection of options if the path is vague:
It’s worth noting that bash has a similar function, but zsh completion is a bit more robust. For instance, we can provide a truncated path and see zsh fill it out for us:
Customizing Behavior
Perhaps the biggest advantage of zsh is its community. Zsh enthusiasts developed the framework known as Oh My Zsh in 2009 and it is now an open source project with over 20,000 forks and 5,000 commits. The inherent customizability of zsh made this community possible, and the Oh My Zsh framework allows novice users to access powerful scripts and plugins for color themes, completion options, and shortcuts.
Globbing
Globbing is a useful tool for searching without a specific path. For example, I have a directory called june_java_class that contains five directories with similar names: day1, day2, and so on. If we run the ls command, we can see the names of all the files in the directory. If we add a specific filename after ls, we can see the contents of that file. But through globbing, we can use the wildcard symbol to ask our terminal to show us the contents of all the files that start with day:
ls day*
Globbing is not unique to zsh, but it is more robust in this shell. A great example of the zsh globbing capabilities, outlined in this article, involves the **/ pattern. The slash refers to directories, so we can use **/ to help us find any directory at any depth. In the TechRepublic example, they are looking for all .sh and .py files in their system, so they run this command (if you test it yourself, just be aware that it could take some time to run):
ls -l **/*.(sh|py)
The -l tag arranges the results in a long list. We then see the **/ to indicate searching for all directories at any level. Next we see another wildcard with a . and (sh|py). This indicates anything that ends with .sh OR .py (hence the pipe separating them). As you might expect, I got a bunch of .sh files back:
Team zsh?
So…out with the old, in with the new, right? It does seem like zsh would be the shell of choice, but I think the real lesson here is that shells are, for most users, interchangeable. In fact, the only reason I was using zsh in the first place was because Apple decided to make it the default for macOS Catalina. I still lean in favor of zsh because of Oh My Zsh, but don’t blame anyone who’s been using bash and doesn’t want to make the shift.
As always, there’s a ton more to learn about shells and scripting, so check out my sources, printed below.