1

I am using Linux Mint 20.1, which is based on Ubuntu 20.04. My kernel is 5.4.0-60-generic. All the commands below are runned in GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)

I have seen the same behaviour with some other commands, but I'll use ping as an example here. Let's see what happens if I run the following commands:

nikolay@KoLin:~$ ping4 -c1 google.com
PING google.com (108.177.14.139) 56(84) bytes of data.
64 bytes from lt-in-f139.1e100.net (108.177.14.139): icmp_seq=1 ttl=107 time=41.3 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 41.301/41.301/41.301/0.000 ms
nikolay@KoLin:~$ ping6 -c1 google.com
ping6: connect: Network is unreachable
nikolay@KoLin:~$

The output is reasonable. The error, obviously, occurs in the second run, because I don't have an IPv6 network configured on my laptop. But the output proves that ping4 and ping6 are two different things in my system. But what are they actually? They are both located in /usr/bin:

nikolay@KoLin:~$ whereis ping{4,6}
ping4: /usr/bin/ping4 /usr/share/man/man8/ping4.8.gz
ping6: /usr/bin/ping6 /usr/share/man/man8/ping6.8.gz
nikolay@KoLin:~$

And what are these files actually?

nikolay@KoLin:~$ ls -l /usr/bin/ping*
-rwxr-xr-x 1 root root 72776 Jan 31  2020 /usr/bin/ping
lrwxrwxrwx 1 root root     4 Jan 11 21:00 /usr/bin/ping4 -> ping
lrwxrwxrwx 1 root root     4 Jan 11 21:00 /usr/bin/ping6 -> ping
nikolay@KoLin:~$

Wow! They are both symbolic links to the same executable /usr/bin/ping! But how's that possible? Is there some magical way to make symbolic link add execution arguments?

Kolay.Ne
  • 121
  • 5
  • 1
    The fact that they are symbolic links is irrelevant to how they are executed by the shell and the kernel, besides permissions. Once the final executable is found on disk it is run and passed as arguments both the name it was invoked with and all arguments. – Patrick Mevzek Jan 16 '21 at 17:43

1 Answers1

1

Turns out that no, it is not possible to create a symbolic link which affects the execution command line arguments. But how does it work with ping then? Apparently, ping uses argv[0] to figure out, which file are we using to run the utility. It is only concerned about the filename. Here is how you can easily check it:

nikolay@KoLin:~/Desktop$ cp /usr/bin/ping ./ping4
nikolay@KoLin:~/Desktop$ ./ping4 -c1 google.com
PING google.com (64.233.164.113) 56(84) bytes of data.
64 bytes from lf-in-f113.1e100.net (64.233.164.113): icmp_seq=1 ttl=107 time=19.2 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 19.152/19.152/19.152/0.000 ms
nikolay@KoLin:~/Desktop$ mv ping4 ping6
nikolay@KoLin:~/Desktop$ ./ping6 -c1 google.com
./ping6: connect: Network is unreachable
nikolay@KoLin:~/Desktop$

Here we are obviously using the same executable (without a link or something like that), and the only difference is its name.

Kolay.Ne
  • 121
  • 5
  • 1
    This also works with hardlinks, and has been a standard trick since the earliest days of Unix. For example `ex` and `vi` are actually the same executable, but start in command or visual mode depending on argv[0]. `gzip/gunzip/zcat` used to do this, but have changed so the latter are now tiny scripts that do `exec gzip -d/-cd "$@"`; some other compressors still do like `xz/unxz/xzcat xzcmp/xzdiff xzgrep/xzegrep/xzfgrep` and `bzip2/bzcat bzcmp/bzdiff bzmore/bzless` – dave_thompson_085 Jan 16 '21 at 05:55
  • @dave_thompson_085, thanks for the details! I wonder why have `gzip/gunzip/zcat` became scripts instead of links? Was there any technical or performance reason? – Kolay.Ne Jan 16 '21 at 12:32