Kind-of decorator functions in bash
The idea in Python
In Python, decorators are an elegant and flexible way to modify the behaviour of a function. The idea is simple: create a function that starts its execution before the function which behaviour we want to modify and this function will call the original function returning its result.
My kind of bash decorators
So, following the same idea of "python decorators", I could write some function in bash to modify the behaviour of my classical linux commands. Lets show a few useful examples:
Helloween cat
I took the artwork from: https://www.asciiartcopy.com/halloween-ascii-art.html - Thank you.
As a first example of "wrapper" function, and given we are 3 days away from helloween, I created a new cat
function this way:
This function behaves as a normal "cat" command, however if you type cat /dev/null
it will show a Helloween Pumkin.
Meassure the time spent by a command
As in the python example, I could measure the time spent by a command with this function:
function meassure() {
local ts=$(date +%s%N)
$@
local r=$?
tspent=$((($(date +%s%N) - $ts)/1000000))
return r
}
The function will calculate the time spent in a command and will set the variable tspent
to the time spent as shown here:
caveat:
The variable tspent
doesn't seem to be set if the output of the function is piped to another command. The workaround for this would be:
❯ r=$(meassure curl https://jicg.eu 2>/dev/null)
❯ echo $r | wc -c ; echo $tspent
32389
222
Log somewhere
Let's say we want to log one command to a file. Whatever the file is marked by the global variable MYLOGFILE
. And if the variable doesn't exists, then it will take the default value of /tmp/mylogfile.log
logit() {
MYLOGFILE=${MYLOGFILE:-"/tmp/mylogfile.log"}
echo ">>>>>" $(date) ">>>>> " $@ >> $MYLOGFILE
$@ | tee -a $MYLOGFILE
local r=$?
echo -e "<<<<<\n" >> $MYLOGFILE
return r
}
So, if we test a couple of commands, then we'll check the "logging":
Final thoughts
It is funny and useful creating this kind of functions in order to help us making our scripts somehow more "controllable", to simplify writing scripts without repeating code or making that easier.
However, writing functions this way doesn't have the power we can have in python, as an example:
ls
is an alias to ls --color
. Inside the function, ls
is no longer an alias. However if we used eval @!
instead of @!
would help us sometimes to run the alias instead of the plain command.