Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unable to run source command with find -exec

Tags:

linux

find

bash

  1. FAIL
find ${settings_base} -type f -exec source {} \;
find: ‘source’: No such file or directory
  1. PASS
for f in $(find ${settings_base} -type f); do
    source "${f}"
done

I just want to know the reason for FAIL.

like image 295
k_vishwanath Avatar asked Mar 04 '26 22:03

k_vishwanath


1 Answers

The -exec predicate of find runs a subprocess. But source cannot be run as a subprocess.

Shell built-ins like source (and cd, etc) modify the environment of the currently running shell instance. They don't exist as external commands (there is no /bin/source or /usr/bin/source etc) because they cannot work as external commands. Recall that a subprocess cannot modify the environment of its parent process, for reasons of security as well as for architectural reasons (see also e.g. Global environment variables in a shell script for background). So as a matter of fact, even if find could somehow execute source, it could only modify the environment of the find process, and then when find exits, any effects of that would be lost, and your currently running shell instance would be back where it was before you ran find.

The workaround you already discovered is the way to do it, though for complete robustness, you would also have to guard against whitespace or other shell metacharacters in the find output. https://mywiki.wooledge.org/BashFAQ/020 has a detailed discussion, but I won't repeat all the nuances and corner cases here; click through to the linked page for that.

while IFS= read -r -d '' f; do
  source "$f"
done < <(find $settings_base -type f -print0)

(Notice that -print0 is a GNU extension, and so not properly portable to various non-Linux platforms.)

Depending on what $settings_base contains, it should probably be double-quoted; if it contains multiple values, put them in an array and use "${settings_base_array[@]}". See also When to wrap quotes around a shell variable?

like image 75
tripleee Avatar answered Mar 06 '26 11:03

tripleee