Bash #3 - PATH-wrapping executables
Posted February 18, 2022 ‐ 3 min read
When fixing up complex systems to our advantage we sometimes need to hook on
the intermediate execution of a program. The UNIX
PATH environment is the
venerable search path for programs available in the environment. In this post
I'll discuss how to use to wrap around the execution of a program.
Previous post: #2.
PATH environment variable is a
:-delimited strings of paths that are
searched in order for executables. For example, a build system may search
gcc compiler in
Let's wrap around
gcc. To create our
gcc wrapper, we need to decided
on a directory on which to place it. The name of the wrapping executable will
gcc so that it gets picked by
PATH lookup. The absolute path
of that directory needs to be prepended to
PATH for the wrapper to be found.
There are various ways to do this. The most common are:
- Prepend in shell command execution
PATH="/directory/to-wrapper:$PATH" <command>, only affecting that command.
- Modify for the current shell script or interactive shell using
Our wrapper can be written as such:
#!/bin/bash # Remove ourselves from $PATH, to prevent infinite # recursion when the wrapped executable is executed # by us. curdir= path_tmp= # Don't let Ctrl-C kill the script # Execute the original program e= # Save exit status # Clear out handler
Notes on what is being done above:
- Important to clear out the directory in which the wrapper resides from
PATH, otherwise we can cause an infinite recursion.
- Forward the exit status of the original program.
- Allow logic to be implemented before and following execution.
- We can control how the original program is executed.
- We can wrap more than one executable with a single wrapper source.
$ ls -l bin total 4 lrwxrwxrwx 1 dan dan 7 Feb 19 09:18 gcc -> wrapper lrwxrwxrwx 1 dan dan 7 Feb 19 09:18 ls -> wrapper -rwxrwxr-x 1 dan dan 389 Feb 19 09:15 wrapper $ export PATH=$(pwd)/bin:$PATH $ ls bin Before execution gcc ls wrapper After execution $ gcc non-existant.c Before execution gcc: error: non-existant.c: No such file or directory gcc: fatal error: no input files compilation terminated. After execution
We should be careful about emitting to stdout and stderr by the wrapping code, and may want to even avoid it completely, lest we break assumptions being made by the upper-level scripts that execute the program we are wrapping.