Reputation: 117
Good afternoon I have the following command to run me 'code.sh' file which I pass a parameter '$ 1' the problem is that I want to run a 'code.sh' with 'source' this is my command:
find . -name "*.txt" -type f -exec ./code.sh {} \;
And I do do well occupied
source ./code.sh
Upvotes: 2
Views: 240
Reputation: 362137
This is tricky. When you source
a script you need to do it in the current shell, not in a sub-shell or child process. Executing source
from find
won't work because find
is a child process, and so changes to environment variables will be lost.
It's rather roundabout, but you can use a loop to parse find
's output and run the source
commands directly in the top-level shell (using process substitution).
while read -d $'\0' fileName; do
source code.sh "$fileName"
done < <(find . -name "*.txt" -type f -print0)
Now what's with -print0
and -d $'\0'
, you ask? Using these two flags together is a way of making the script extra safe.† File names in UNIX are allowed to contain lots of oddball characters including spaces, tabs, and even newlines. While newlines are rare, they are indeed legal.
-print0
tells find
to use NUL characters (\0
) to separate the file names rather than the default newlines (\n
). Doing this means file names containing \n
won't mess up the loop. Using \0
as a separator works well because \0
is not a legal character in file names.
-d $'\0'
‡ does the same thing with read
on the other side. It tells read
that lines are delimited with \0
instead of \n
.
† You may have seen this trick before. It's common to write find ... -print0 | xargs -0 ...
to get the same sort of safety when pairing find
with xargs
.
‡ If you're wondering about $'...'
: that's Bash ANSI-C quoting syntax for writing string literals containing escape codes. Dollar sign plus single quotes. You can write $'\n'
for a newline or $'\t'
for a tab or $'\0'
for a NUL.
Upvotes: 3
Reputation: 532398
You won't be able to use find
in this way; it will always execute a command in a separate process, not the current shell. If you are using bash
4, there's a simple alternative to using find
:
shopt -s globstar
for f in **/*.txt; do
[[ -f $f ]] && source code.sh "$f"
done
Upvotes: 2