28

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?

42

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-)
  • See also: ssh-argv0 – jordanm May 25 '13 at 0:19
  • 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 '13 at 3:28
  • 1
    The arguments to the main are reversed. argc comes before argv. – Bakuriu May 25 '13 at 8:02
  • 3
    in C, you can't make a switch statement with strings. – BatchyX May 25 '13 at 13:51
  • 3
    +1 for "I don't know who I am" :) – a CVn May 25 '13 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.