Why are reboot, shutdown and poweroff symlinks to systemctl?

13,834

Many programs make use of this technique where there is a single executable that changes its behavior based on how it was executed.

There's typically a structure inside the program called a case/switch statement that determines the name the executable was called with and then will call the appropriate functionality for that executable name. That name is usually the first argument the program receives. For example, in C when you write:

int main(int argc, char** argv)

argv[0] contains the name of the called executable. At least, this is the standard behaviour for all shells, and all executables that use arguments should be aware of it.

Example in Perl

Here's a contrived example I put together in Perl which shows the technique as well.

Here's the actual script, call it mycmd.pl:

#!/usr/bin/perl

use feature ':5.10';

(my $arg = $0) =~ s#./##;

my $msg = "I was called as: ";

given ($arg) {
  $msg .= $arg  when 'ls';
  $msg .= $arg  when 'find';
  $msg .= $arg  when 'pwd';
  default { $msg = "Error: I don't know who I am 8-)"; }
}

say $msg;
exit 0;

Here's the file system setup:

$ ls -l
total 4
lrwxrwxrwx 1 saml saml   8 May 24 20:49 find -> mycmd.pl
lrwxrwxrwx 1 saml saml   8 May 24 20:34 ls -> mycmd.pl
-rwxrwxr-x 1 saml saml 275 May 24 20:49 mycmd.pl
lrwxrwxrwx 1 saml saml   8 May 24 20:49 pwd -> mycmd.pl

Now when I run my commands:

$ ./find 
I was called as: find

$ ./ls
I was called as: ls

$ ./pwd
I was called as: pwd

$ ./mycmd.pl 
Error: I don't know who I am 8-)
Share:
13,834

Related videos on Youtube

Gradient
Author by

Gradient

Updated on September 18, 2022

Comments

  • Gradient
    Gradient almost 2 years

    In Arch Linux, if I do ls -l in /sbin, I can see that reboot, shutdown and poweroff are all symlinks to /usr/bin/systemctl. But issuing reboot, shutdown and systemctl commands obviously does not all have the same behaviour.

    Is ls -l not showing me full information regarding symlinks? How can I, for example, know what the real symlink of reboot is?

  • jordanm
    jordanm about 11 years
    See also: ssh-argv0
  • Gradient
    Gradient about 11 years
    Thank you! This is a trick I didn't think about.
  • Fake Name
    Fake Name about 11 years
    This is actually how BusyBox works. It has a single binary that acts as most of the common GNU utilities.
  • Bakuriu
    Bakuriu about 11 years
    The arguments to the main are reversed. argc comes before argv.
  • BatchyX
    BatchyX about 11 years
    in C, you can't make a switch statement with strings.
  • slm
    slm about 11 years
    Thanks for the feedback. Someone else added that bit to my answer. This answer is just giving the OP the gist of how/why the links are present in his /sbin directory. There are ways to get the functionality via switch as described here in C/C++. The concept is what matters not the semantics.
  • user
    user about 11 years
    +1 for "I don't know who I am" :)
  • pa4080
    pa4080 about 6 years
    I've copy/paste part of this answer in AU where is provided also and Bash example: askubuntu.com/a/1023946/566421
  • Grimm
    Grimm about 3 years
    I just wondered why this isn't considered bad programming style: By making systemctl doing the switch on the various names of callers ('shutdown', 'reboot', etc.) effectively additional dependencies are created. Wouldn't it be better to let 'shutdown' just be a simple command calling 'systemctl poweroff' (and let systemctl as-is)?