Zsh Features

Whether or not you realize it, you are probably already using at least two shells in Linux. Bash is the default shell installed with almost all Linux systems, and if so it handles the command line. By default, the lightweight ash, aka dash, is the default used to execute scripts, however.

Note that the “shebang” line at the start of a script specifies which shell to use, even if the default is something else: #!/bin/sh (or no shebang line at all) will cause the script to be executed by dash. #!/bin/bash uses bash for execution, etc.

Z shell (zsh) is also basically a Bourne-type shell, but it has quite a few features that are not present in Bash or Dash. Some of these features are quite esoteric, but some are so useful that (IMHO) it is a good idea to install and become familiar with it, and then make it your default shell for all command-line activities.

Here are some of the zsh features which I find handy enough to remember and regularly use. Most of them require the exended_glob option to be set in .zshrc.

If I’ve convinced you, get it with

sudo apt-get install zsh
and then make it your default shell with
sudo chsh /usr/bin/zsh

The Parallel Command

The command must be installed:

sudo apt-get install parallel
or whatever. In use, it causes all available CPU cores to be used in parallel to execute a specified command sequence. The syntax is unbelievably complex (the man page is 2,400 lines long!) but here are a few simple examples:
parallel gzip ::: *txt
will run gzip to compress all text files in the current directory. If you have a 4-core CPU, this will be done four at a time, with a significant speed-up. (It almost certainly won’t be four times as fast, because only CPU time can be multiplexed this way; disk reading and writing is still using only one disk and will happen serially. This implies that using parallel would be useless to, for example, copy a lot of files from one spot to another.) The ::: is a marker that means “file names follow” — the default is to use standard input.

Here’s an actual example of an alias I use, called 2azw3, to convert e-book files into Amazon’s AZW3 format (a better MOBI):

alias 2azw3='parallel --progress ebook-convert {} .azw3 :::'
The new stuff is the --progress option to show the output one job at a time on the screen, and the {} marker to show where to insert each filename when it isn’t at the end of the iterated command. In other words,
2azw3 file1.html file2.mobi file3.txt file4.epub
will actually run
ebook-convert file1.html .azw3
ebook-convert file2.mobi .azw3
ebook-convert file3.txt .azw3
ebook-convert file4.epub .azw3
in parallel, creating file1.azw3, file2.azw3 and so on. If I had a 2-core CPU, they’d be done two at a time.

If you’re a real masochist, go ahead and read the man page, which covers redirection, executing code in parallel on other machines, and much else, but you can speed up some looonnnnggg operations just with what I’ve shown.

As I mentioned in my meeting announcement, another real time-saver is using parallel with the convert program, part of the imagemagick suite. Just type this on the command line to create 120x96 versions of all image files in the current directory:

parallel convert -geometry 120x96 {} th-{} ::: *jpg *gif *png
where the new files will be called th-image1.jpg, th-becky.png and so on. This is not only faster to run, it’s faster to type than having to input
for i in *{jpg,gif;png}; do convert -geometry 120x96 $i th-$i; done

The only real limitation on parallel is that the command(s) it executes cannot be aliases or (without an extra step) functions; they must be executable scripts or binary programs.


Last modified: Tue Aug 13 22:49:06 UTC 2013