Bash: function "command not found" in a subshell
A function defined in your shell is invisible to subshells and child processes unless exported with `export -f` or sourced in the child.
Error String
bash: my_function: command not found
Tldr
Bash functions are local to the shell that defined them. `bash -c` subprocesses, scripts, and other tools that exec a new shell don't inherit them. Export with `export -f my_function`, or source the defining file from the child.
Cause
Common when piping to `sudo bash -c …` or `parallel` — the function exists in the calling shell but the child shell starts empty.
Repro
greet() { echo "hi $1"; }
greet alice # works
bash -c 'greet bob' # command not foundFix
greet() { echo "hi $1"; }
export -f greet
bash -c 'greet bob' # hi bob
# Or source the file in the child:
bash -c 'source /path/to/lib.sh; greet bob'Explanation
`export -f` works for Bash subshells but not POSIX `sh`. For maximum portability, put helpers in a sourceable file and source it explicitly from every entry point.
Faq
Q
Why is my function missing inside find -exec?
A
`find` executes a new process, and functions are not inherited. Export it and invoke through `bash -c`, or use a wrapper script.
Q
Does sourcing inside a function make it global?
A
Yes, sourced definitions land in the current shell — but only from the point of sourcing onwards.
Deep Dive
Heading
Definition order matters
Body
A shell script is executed as it is read, so a function must be defined before the line that calls it. Definitions inside an `if` branch that did not run, or in a file that was never sourced, leave the name undefined. Check with `declare -f name` at the call site: it prints the body if the function exists and returns non-zero if it does not. `type name` shows whether the name resolves to a function, builtin, alias or file.
Heading
Subshells and exported functions
Body
Functions do not cross process boundaries. A function is invisible to `xargs`, `find -exec`, `sudo`, `su`, `ssh`, or any separate `bash` invocation unless you export it with `export -f name` and the child is Bash. `xargs bash -c 'my_func "$@"' _` works only after the export. In `sudo` the environment is scrubbed by default, so the cleanest approach is to move shared helpers into a library file and `source` it in every context that needs them.
Checklist
Move the definition above the first call.
Confirm the sourced library path is correct and readable.
Run `declare -f name` at the call site to check visibility.
Use `export -f` for functions consumed by child Bash processes.