When I learn a new command-line tool, I have taken to checking the documentation for “dry-run” functionality. Using an option
--dryrun) simulates a command without actually running it. That way, if there is an error or something you didn’t expect, you can make changes before actually running the command for real. Especially when the command may cause expense (opening a connection and writing files to a server) or some far-reaching change (deleting or altering code or state), it’s a good idea to take a little time to be sure you expect what is coming.
Below I list six programs that have dry-run options, illustrating various characteristics of the principle: Git, Homebrew, Make, Bash, TeX Live Manager, and Trial. But before I begin, I want to make two larger points.
First, one of the most common causes of inadvertent damage at the command line is the use of
rm to delete files and directories. And
rm has no dry-run option at this time. But there is
trash-cli, which moves files to the trash while leaving you the option of restoring anything you inadvertently delete. Note that the author recommends against mapping
Second, I’m aware of three issues to be cautious about when doing dry runs.
- A dry run may print full prospective output to the terminal; but sometimes, depending on the program, it merely reports errors. It is good to know which of these you are getting.
- Some programs use
-nas shorthand for the dry-run option or even instead of it. But the
-noption is also widely used for “number” and for “not [some other default functionality]”, and you can get into a serious pickle if
-ndoesn’t behave as you thought it would. Read the docs, Comrade Coder.
- Some programs report to you explicitly that a dry-run is merely that; others assume you are aware of what you are doing. That means that if you are not careful, you may think you have run a command when you have only done a dry run of it. In the first Git example, below, a dry run produces output indistinguishable from actually running the command; in the second and third Git examples, the output distinguishes them quite clearly.
Version control systems tend to have dry-run functionality, since you can create a huge snarl of work for yourself and others if you gum up a repository with erroneous commits. Here are two examples from Git, where
--dry-run is usually available; in some cases
-n has the same effect:
$ git add -Avn .. add ...
I am asking git to verbosely
add any changed files in the current directory and below, including any files previously committed. The output gives no indication that this is a dry run, so you must remember to use
git add -Av ... afterwards so that the files are actually staged.
$ git commit --dry-run On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: ...
An actual commit, in contrast, would report something like this:
[master 52a0905] <commit message> 1 file changed, 19 insertions(+), 3 deletions(-)
If you include other options with
git commit, you will see that full prospective commit behavior in the terminal output. I’m partial to
git commit -v for “verbose” commit-content and
git commit -o for committing “only” specified files.
git commit -n is not the same as
git commit --dry-run; this is a case where you must avoid being lazy about typing out the full option.
When pushing, the dry run does actually contact the server but omits the rest of the rigamarole:
$ git push --dry-run Host key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 To email@example.com:brannerchinese/MelodyOfLyric.git 1bceabf..53033b0 master -> master $ git push Host key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 Counting objects: 9, done. Delta compression using up to 8 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 484 bytes | 0 bytes/s, done. Total 5 (delta 4), reused 0 (delta 0) To firstname.lastname@example.org:brannerchinese/MelodyOfLyric.git 1bceabf..53033b0 master -> master
Homebrew, the package management system for Unix software on Darwin (Macintosh), allows a
--dry-run option, which can be shortened to
$ brew link -n ghostscript Would link: /usr/local/bin/dvipdf /usr/local/bin/eps2eps /usr/local/bin/font2c /usr/local/bin/gs /usr/local/bin/gsbj /usr/local/bin/gsc ... $ brew link ghostscript Linking /usr/local/Cellar/ghostscript/9.15... 64 symlinks created
Its output is more explicit than actually running the command, and it thoughtfully uses the modal auxiliary verb “would” to indicate the counterfactual state.
make program is a build-process manager. Running it can initiate a very long process during which many sorts of things may go wrong, so it is a good idea to do a dry run first. Using
$ make -n
stdout all commands that would be executed by
make, without actually executing them; there is not necessarily any output other than those commands. But I have seen a case (
mailvelope) where it marks prospective output as counterfactual, too, by use of
echo: so rather than
build - copy common folder and dependencies
echo "build - copy common folder and dependencies"
-n can be replaced more explicitly with
--dry-run. Both options are also available for
rake (Ruby’s equivalent to
The Bash Unix shell, when invoked to read shell scripts, has a dry-run option:
bash -n <script>
<script> without executing it and reports any syntax errors. It does not show the actual commands issued or their results, and if there are no syntax errors there will be no output at all.
5. TeX Live Manager (tlmgr)
TeX Live Manager, the package manager for LaTeX, has a
--dry-run option for
backup, and several other commands. It shows the expected output for the command, though without valid download-timing data:
$ sudo tlmgr update --all --dry-run Password: tlmgr: package repository http://ctan.math.washington.edu/tex-archive/systems/texlive/tlnet update: dry run, no changes will be made tlmgr: saving backups to /usr/local/texlive/2014/tlpkg/backups [ 1/18, ??:??/??:??] update: biblatex-anonymous [53k] (35451 -> 35491) [ 2/18, 00:00/00:00] update: biblatex-realauthor [76k] (35452 -> 35499) [ 3/18, 00:00/00:00] update: bibleref-french [642k] (27098 -> 35497) ...
TeX Live Manager tells you clearly, “dry run, no changes will be made;” here is how the actual output would look:
$ sudo tlmgr update --all Password: tlmgr: package repository http://ctan.mirrors.hoobly.com/systems/texlive/tlnet tlmgr: saving backups to /usr/local/texlive/2014/tlpkg/backups [ 1/18, ??:??/??:??] update: biblatex-anonymous [53k] (35451 -> 35491) ... done [ 2/18, 00:03/16:09] update: biblatex-realauthor [76k] (35452 -> 35499) ... done [ 3/18, 00:05/11:00] update: bibleref-french [642k] (27098 -> 35497) ... done ... tlmgr: package log updated: /usr/local/texlive/2014/texmf-var/web2c/tlmgr.log running mktexlsr ... done running mktexlsr. running mtxrun --generate ... done running mtxrun --generate. running updmap-sys ... done running updmap-sys.
Trial is a Python unit-testing system for use with Twisted. Running
$ trial -n
will iterate through all tests and report them passing, without actually running them. Option
-n can be replaced more explicitly with
Many other programs —
— and countless others support dry-run functionality.
Read the docs and do dry runs.