Would you like to have a smile painted on your lips again while thinking about the animated film "The Twelve Tasks of Asterix"? Where one of the tasks Asterix and Obelix have to solve is finding the permit A38 in "The Place That Sends You Mad", a bureau house which is riddled with extreme bureaucracy and turns the two nearly insane? But now in the context of finding out which executable will be actually run while executing a command from a Terminal shell prompt?
In order to be able to experience how far goes the insane madness of indirections while starting an executable from a shell command prompt on Linux Mint 21.2 Xfce system it is helpful to use the following script I had given the name whichf
( available also on github as part of the oOo repository ):
#!/bin/bash
# Custom which by oOosys as part of the oOo system 2023-12-31_21:26
# goes down a chain of links and scripts to the actual executable
# Other method of getting the dir part of full path fname:
# ~ $ FPFNAME="/home/user/dir/fname.ext"
# ~ $ DIR=$(echo $FPFNAME | rev | cut -d"/" -f2- | rev)
# rev "/home/user/dir/fname.ext" ->
# cut -d"/" -f2- txe.emanf/rid/resu/emoh/ ->
# rev rid/resu/emoh/ -> /home/user/dir
BCKPCWD=$(pwd) # save current working directory
s0=$1 sb=' '
echo $s0
s1=$(which $s0)
echo "$sb-> $s1"
if [ ! -e "$s1" ] ; then
exit
fi
while : ; do
#DIR=$(dirname $s1) # fails in case of spaces in file name - always use "${s1}"
DIR="$(dirname "${s1}")" # FILE="$(basename "${s1}")"
SIZE=$(stat -c%s "$s1") # provide file size of the executable
s2=$(file $s1 2>/dev/null) s3=${s2##*:} sb=" $sb"
echo "$sb-> $s3 ( fileSize = $SIZE bytes )"
s4=${s3##* } # get the last column with the file name path
cd $DIR # required for symbolic link with relative path
# use $(pwd) to obtain the full path name of current directory
if [ ! -e "$s4" ] ; then
if [[ $s3 == *"text"* ]]; then
scriptShebang=$(head -n 1 $s1)
scriptInterpreterPath=$( echo $scriptShebang | cut --delimiter='!' --fields=2 )
echo $scriptShebang
whichf $scriptInterpreterPath
fi
cd $BCKPCWD # restore current working directory
break # exit the loop and the script
fi
s1=$s4
done
<<REM
which is a shell script which loops over paths provided in the $PATH environment
variable and extracting them by splitting $PATH on colons.
REM
Below what you can find out using whichf
about the actual executable file which will be run if you use the which
command:
o@s:~$ whichf which
which
-> /usr/bin/which
-> symbolic link to /etc/alternatives/which ( fileSize = 23 bytes )
-> symbolic link to /usr/bin/which.debianutils ( fileSize = 26 bytes )
-> POSIX shell script, ASCII text executable ( fileSize = 946 bytes )
#! /bin/sh
/bin/sh
-> /bin/sh
-> symbolic link to dash ( fileSize = 4 bytes )
-> ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f7ab02fc1b8ff61b41647c1e16ec9d95ba5de9f0, for GNU/Linux 3.2.0, stripped ( fileSize = 125688 bytes )
From the above you can see that which
is found in one of the $PATH directories and is actually a symbolic link to a symbolic link which leads to a shell script which then points to a /bin/sh
being a symbolic link pointing finally to the actual executable file which will be run in order to execute the script.
So in order to get to the actual executable file you need to go through three (3) symbolic links and one (1) shell script which then need to loop over the content of the $PATH environment variable in order to determine its output. This makes a total of five (5) indirections on the way to the final outcome.
This article is part of the series of contributions about
Top comments (0)