In Bash, declare -f <functionName>
can be used to emit function definitions. I want to use this as I'm writing code to allow me to have Bash annotations that modify function content.
I'm running into a problem in that some allowed function names can be used, but their definitions cannot emitted. The following code demonstrates that function names containing square brackets cannot be emitted, while other names with special characters can be emitted.
demo.sh
#!/bin/bash
main()
{
# Gather function names
local SourceFile="$1"
local FunctionNames
FunctionNames=(
$(
bash <(
cat "$SourceFile"
echo 'declare -F'
) 2>&1 |
grep 'declare -f' |
sed 's|.* ||'
)
)
# Show function names and that special characters work
printf 'Function: %s\n' "${FunctionNames[@]}"; echo
. "$SourceFile"
test.
echo
# Show function definitions
local FunctionName
for FunctionName in "${FunctionNames[@]}"; do
echo "$(
bash <(
cat "$SourceFile"
echo "declare -f '$FunctionName'"
)
)"
done
}
main "$@"
testdata.sh
#!/bin/bash
f:()
{
echo "In f:"
}
f[]()
{
echo "In f[]"
}
test.()
{
echo "In test."
f:
f[]
}
Invocation
$ ./demo.sh testdata.sh
Function: f:
Function: f[]
Function: test.
In test.
In f:
In f[]
f: ()
{
echo "In f:"
}
/dev/fd/63: line 19: declare: `f[]': not a valid identifier
test. ()
{
echo "In test.";
f:;
f[]
}
I have tested this on CentOS 7 using the stock Bash 4.2.46(1)-release and with Bash 4.4.0(1)-release that I built from source. In both cases the above behavior happens.
Note: the use of <()
and $()
above is used to ensure that only those functions that are in the $SourceFile
are processed (otherwise functions in demo.sh would also be included).
So, my questions are:
- Is it possible using Bash 4.2.46(1)-release to emit function definitions for function names that include bracket characters by some other mechanism?
- Is it possible using Bash 4.4.0(1)-release?
- Is this a bug?
This question is specific to square brackets in function names.