Shell builtin versions of standard commands have drawbacks

September 29, 2017

I'll start with a specific illustration of the general problem:

bash# kill -SIGRTMIN+22 1
bash: kill: SIGRTMIN+22: invalid signal specification
bash# /bin/kill -SIGRTMIN+22 1

The first thing is that yes, this is Linux being a bit unusual. Linux has significantly extended the usual range of Unix signal numbers to include POSIX.1-2001 realtime signals, and then can vary what SIGRTMIN is depending on how a system is set up. Once Linux had these extra signals (and defined in the way they are), people sensibly added support for them to versions of kill. All of this is perfectly in accord with the broad Unix philosophy; of course if you add a new facility to the system you want to expose it to shell scripts when that's possible.

Then along came Bash. Bash is cross-Unix, and it has a builtin kill command, and for whatever reason the Bash people didn't modify Bash so that on Linux it would support the SIGRTMIN+<n> syntax (some possible reasons for that are contained in this sentence). The results of that are a divergence between the behavior of Bash's kill builtin and the real kill program that have become increasingly relevant now that programs like systemd are taking advantage of the extra signals to allow you to control more of their operations by sending them more signals.

Of course, this is a generic problem with shell builtins that shadow real programs in any (and all) shells; it's not particularly specific to Bash (zsh also has this issue on Linux, for example). There are advantages to having builtins, including builtins of things like kill, but there are also drawbacks. How best to fix or work around them isn't clear.

(kill is often a builtin in shells with job control, Bash included, so that you can do 'kill %<n>' and the like. Things like test are often made builtins for shell script speed, although Unixes can take that too far.)

PS: certainly one answer is 'have Bash implement the union of all special kill, test, and so on features from all Unixes it runs on', but I'm not sure that's going to work in practice. And Bash is just one of several popular shells, all of whom would need to keep up with things (or at least people probably want them to do so).

Comments on this page:

From at 2017-09-30 09:23:51:

Bash supports the signals, but some of them are named SIGRTMIN-xx instead. (They didn't think to implement a generic parser, and instead used fixed labels for all of them...)

Regarding the original problem, your systemd-analyze might already have subcommands for setting log levels.

From at 2017-09-30 09:27:13:

Err, mistyped – in bash, some are SIGRTMIN+foo but others are SIGRTMAX-bar. Of course both would be equivalent, but for some reason bash uses MIN for half of them, MAX for the rest.

By Anonymous Coward at 2017-09-30 12:36:41:

I wonder if this can be said to be a failing of the way Linux works nowadays (and one that couldn't possibly have been predicted when Linus started working on it); It's by far the biggest open-source project, yet it's often the work (or lack thereof) of a single individual to keep some vital piece of software not just up-to-date, but also make decisions on what they want to include based on what the Linux kernel supports vs what's available on other open-source systems.

It reminds me a bit of how ifconfig, netstat, route and such have been replaced by the iproute2 package on Linux because nobody stepped up to maintain them, so they weren't kept up with all the features, and if you make your money being a sysadmin on a non-Linux Unix-like, with systemd and iproute2 it can be a non-trivial task to have to work with it.

Written on 29 September 2017.
« More on systemd on Ubuntu 16.04 failing to reliably reboot some of our servers
The origin of POSIX as I learned the story (or mythology) »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Sep 29 21:40:28 2017
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.