34

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?

1

1 Answer 1

47

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-)
10
  • 4
    This is actually how BusyBox works. It has a single binary that acts as most of the common GNU utilities.
    – Fake Name
    May 25, 2013 at 3:28
  • 1
    The arguments to the main are reversed. argc comes before argv.
    – Bakuriu
    May 25, 2013 at 8:02
  • 4
    in C, you can't make a switch statement with strings.
    – BatchyX
    May 25, 2013 at 13:51
  • 4
    +1 for "I don't know who I am" :)
    – user
    May 25, 2013 at 14:56
  • 1
    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)?
    – Grimm
    Apr 1, 2021 at 18:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .