Wandering Thoughts archives

2016-03-07

Why it makes sense for true and false to ignore their arguments

It's standard when writing Unix command line programs to make them check their arguments and complain if the usage is incorrect. It's reasonably common to do this even for programs that don't take options or positional arguments. After all, if your command is supposed to take no arguments, it's really an error if someone runs it and gives it arguments.

(Not all scripts, programs, and so on actually check this, because you usually have to go at least a little bit out of your way to look at the argument count. But it's the kind of minor nit you might get code review comments about, or an issue report.)

true and false are an exception to this, in that they more or less completely ignore any arguments given to them. Part of this behavior is historical; the V7 /bin/true and /bin/false were extremely minimal, and when you're being minimal it's easiest to not even look at the arguments. But beyond the history, I think that this is perfectly sensible behavior for true and false because it makes them universal substitutes for other commands, for when you want to null out a command so that it does nothing.

Want to make a command do nothing but always succeed? Simple: 'mv command command.real; ln -s /bin/true command'. Want to do the same thing but have the command always fail? Use false instead of true. Sure, you can do the same thing with shell scripts that deliberately ignore the arguments and just do 'exit 0' or 'exit 1', but this is a little bit simpler and matches the historical behavior.

(You can also do this in shell scripts as a way of creating a 'don't actually do anything' mode, but there are probably better patterns there.)

On that note, it's interesting to note that although GNU true and false have command line options that will cause them to produce output, there is no way to get them to return the wrong exit status. And while they respond to --help and --version, they silently ignore other options (as opposed to, say, reporting a syntax error).

(This entry was sparked by Zev Weiss's mention of true in his comment on this entry.)

Sidebar: true and false in V7

In V7 Unix, true is an empty file and false is a file that is literally just 'exit 1'. Neither has a #! line at the start of the file, because that came in later. That true is empty instead of 'exit 0' saves V7 a disk block, which probably mattered back then.

unix/TrueFalseAndArguments written at 23:13:13; Add Comment

Apt-get and its irritating lack of easy selective upgrades

One of my many irritations with apt-get is that it doesn't easily allow you to only apply some of the pending updates. Sure, often you want to apply all of the updates (at least all of the unheld updates), but there are any number of cases where you want to be more selective. Sometimes you are in a rush and you want to apply only a few very urgent updates. Sometimes you want to apply updates in a specific order, updating some packages before others. Sometimes you want to apply most updates but temporarily exclude some that you consider low priority or disruptive.

With a package manager like yum (or now dnf) you can easily do either of these. If you just want to exclude some packages, you do that with '--exclude'; if you only want to upgrade some packages, you do that by supplying them as explicit arguments. And it's harmless to be a bit broad in your explicit arguments, because you're specifically only upgrading existing packages; you'll never install new ones out of nowhere.

apt-get does not support this usage as far as I can see. apt-get upgrade takes no package list and has no way of excluding some packages; it is an all or nothing operation, where the only way you have of being selective is to hold packages in advance in order to block their upgrades. In order to upgrade packages selectively, you must turn to 'apt-get install', probably with '--only-upgrade' so that you don't accidentally install new packages. And as far as I can tell this has no equivalent of yum's --exclude, so there's no easy way I can see of saying 'upgrade everything except the following packages'.

(apt-get install does at least support wildcards, or more exactly POSIX regular expressions. I don't know why they decided to use regular expressions instead of shell globbing, but it feels like a very Debian decision, especially the detail that it defaults to matching substrings.)

'apt-get install --only-upgrade PKG ...' solves about half of the problem (although clumsily) so I'm less disgruntled than I was at the start of writing this entry, but it's still not particularly great.

linux/AptGetSelectiveUpgradePain written at 01:14:06; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.