The oOo way (Appendix 1) : whichf
Tags: programming, shell, bash
Published: 2023-12-31 21:11:46

Would you like to have a smile painted on your lips again while thinking about the animated [film](https://en.wikipedia.org/wiki/The_Twelve_Tasks_of_Asterix) "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`](https://github.com/oOosys/oOo/blob/main/shPrgLang/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_
- [**The revolutionary concept of oOo**](https://dev.to/ooosys/the-revolutionary-concept-of-ooo-m98)