Achieve Local Function
Bash does not support local functions, but depending on your specific script and architecture you can control the scope of your function name through subshells.
By replacing the {..}
with (..)
in your definition, you'll get the output you want. The new definition of usage
will be limited to the function, but so will e.g. any changes to variables:
#!/bin/bash
usage()
{
echo "Overall Usage"
}
function_A()
( # <-- Use subshell
usage()
{
echo "function_A Usage"
}
for i in "$@"; do
case $i in
--help)
usage
shift
;;
*)
echo "flag provided but not defined: ${i%%=*}"
echo "See '$0 --help'."
exit 0
;;
esac
done
)
function_A --help
usage
From man bash
:
Compound Commands
A compound command is one of the following:
(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list. ...
- Suppose we have test.sh:
#!/usr/bin/sh
topFunction1() {
# start subshell
(
innerFunction1() {
echo "innerFunction1"
}
echo "topFunction1 can call $(innerFunction1) from within the subshell"
)
# end subshell
innerFunction2() {
echo "innerFunction2"
}
}
topFunction2() {
echo "topFunction2"
}
- Now let's do
source test.sh
.
The following command is successful:
topFunction2
The following commands fail:
innerFunction1
innerFunction2
- Now if we do
topFunction1
we'll get an output containinginnerFunction1
output:topFunction1 can call innerFunction1 from within the subshell
At this point the following commands are successful:
topFunction1
topFunction2
innerFunction2
One can notice that now innerFunction2
it's visible globally after the call to topFunction1
.
However innerFunction1
it's still 'hidden' for calls out of the subshell and this is what you probably want.
Another call to innerFunction1
will fail.