0

I am trying to read all the files that end with .env inside the config_files folder and then run the export command to have them available as environment variables.

So far I have tried:

#! /bin/bash
for file in "$(find ~/config_files -maxdepth 3 -name '*.env')"; do export $(grep -v '^#' $file | xargs); done

and

#! /bin/bash
for file in  "$(find ~/config_files -regex '.*/.*\.\(env\)$')"; do export $(xargs < $file); done

Which would always end up having a declare -x issue like:

declare -x COLORTERM="truecolor"

I have also tried adding -print to the bash file like:

for file in "$(find ~/.ros/PS_AD/config_files -maxdepth 3 -name '*.env' -print)"; do export $(grep -v '^#' $file | xargs); done

But then I got:

./script: line 3: export: `/home/imr/config_files/docker-image/docker_specs.env:random=1': not a valid identifier

The *.env files look like:

random=1

What am I missing?

EDIT: Now I am using the proper way ... with IFS and read

find ~/config_files -name '*.env' -print0 |
    while IFS= read -r -d '' line; do
        echo $line
        set -a
        . "$line"
        set +a
    done

but the environment variables are still not set

EDIT: Now also using the pipeline workaround doesn't solve the issue

while IFS= read -r -d ''  p
do
  set -a; . "$p"; set +a
done < <(find ~/config_files -name '*.env' -type f -print0)
8
  • 2
    Note that when reviewing the answers on the duplicat at stackoverflow.com/questions/19331497/…, I strongly advise ignoring any answer that says a word about xargs, and sticking to those that use set -a or set -o allexport. Commented Feb 10, 2023 at 14:28
  • I tried doing what you guys suggested, but it still doesn't work Commented Feb 10, 2023 at 14:30
  • It works except for the pipeline. Read BashFAQ #24 Commented Feb 10, 2023 at 15:29
  • Instead of piping from find into your loop, use while ...; done < <(find ~/config_files -name '*.env' -print0) -- that way the while loop, and thus the env, runs in your main shell instance, not a subshell, so the variables stay set after the loop has exited. Commented Feb 10, 2023 at 15:30
  • it still doesn't do the trick. I tried what you suggested and the env variables weren't set. Later, I tried using mkfifo my_pipe but then it would get stuck. If I try to run it again it complains that the file my_pipe already exists Commented Feb 13, 2023 at 7:54

1 Answer 1

0

You should use while IFS= to 'loop' over the lines, then use export $(xargs < path) to export those to the shell:

$ cat foo/a.env
foo=bar
$
$ find /tmp/foo -type f -print0 | \
    while IFS= read -r -d ''  p; do export $(xargs < $p); done
$
$ echo $foo
bar
$
Sign up to request clarification or add additional context in comments.

4 Comments

I'd suggest replacing export $(xargs < $p) with set -a; . "$p"; set +a, assuming the files are in valid shell syntax (and if they're not, one has bigger problems). An unquoted expansion onto the export command line isn't going to behave well when you have values with spaces, values where the unquoting rules xargs follows aren't quite right, etc. (xargs unquoting rules are subtly incompatible with POSIX sh rules -- check behavior of variables with line continuations, f/e).
that works if I run on the terminal, but doesn't work on my bash file
I am using #!/bin/bash
this approach had an issue because of the pipeline, as pointed out in BashFAQ by @Charles Duffy

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.