0

I currently have a bash script that loops through all .env files, these files are nested in subdirectories, and I want to source each env file (making them seen under printenv command), how do I go about it?

Currently, I have this script

#!/bin/bash

for i in $(find . -type f -iname '.env'); do
    echo $i
done

Which outputs:

./packages/database/.env
./packages/api/.env
./packages/email/.env
./apps/starter/.env

This does not work:

for i in $(find . -type f -iname '.env'); do
    source $i
done
Damiisdandy
  • 357
  • 3
  • 12
  • 5
    describe "does not work" in more detail – glenn jackman Jan 13 '23 at 17:40
  • Mind, `for i in $(anything); do ...` is bad practice to start with, for the reasons described in [DontReadLinesWithFor](https://mywiki.wooledge.org/DontReadLinesWithFor) – Charles Duffy Jan 13 '23 at 18:20
  • Anyhow -- are you expecting all the variables to still be set after your script exits? If so, _that's_ your problem; a script runs in a different shell interpreter than the interactive prompt it was started from; variables set in that interpreter aren't also set in the interactive shell. – Charles Duffy Jan 13 '23 at 18:20
  • Another potential source of issues is a non-default IFS variable; `IFS=/` will wreak havoc with the loop given in the question. But we really need to know how you came to the conclusion that it "does not work" before we know what _kind_ of not-working it is and suggest an appropriate solution. – Charles Duffy Jan 13 '23 at 18:22
  • Anyhow: Are you running `printenv` _from the same script_, or are you running it after the script exits? The former will work, the latter isn't supposed to. – Charles Duffy Jan 13 '23 at 18:26
  • If the above _is_ the misunderstanding underlying this question, then the question is duplicative of [Can I export a variable to the environment from a bash script without sourcing it?](https://stackoverflow.com/questions/16618071/can-i-export-a-variable-to-the-environment-from-a-bash-script-without-sourcing-i), the upshot of which is that _your script itself_ needs to be sourced for variables set when it sources other scripts to remain available after it's exited. – Charles Duffy Jan 13 '23 at 20:26
  • @CharlesDuffy "it does not work" I mean when I try to run the application, it doesn't recognize the env variables, I guess the issue is because of what you stated. "a script runs in a different shell interpreter than the interactive prompt it was started from". so the question is how can I source env variables that exist in the subdirectories of a parent directory? – Damiisdandy Jan 14 '23 at 06:32
  • @Damiisdandy, the change you need is to run _the script itself_ by sourcing it -- or just change it from a script into a shell function outright. The important thing is not to have any process boundaries between the place you want to use the variable and the place where the variable is defined. – Charles Duffy Jan 14 '23 at 18:09
  • BTW, personally I would write a program to act as described in the question as `while IFS= read -r -d '' envSource <&3; do source "$envSource"; done 3< <(find "$PWD" -type f -iname '.env' -print0)`. That way the paths are fully qualified so it doesn't matter if something you're sourcing runs `cd`; the names are correctly quoted and escaped so things still work right if a directory name has spaces, newlines, or glob characters; and the output of `find` is outside stdin so if you source something that _reads_ stdin it doesn't stop later filenames from being correctly processed. – Charles Duffy Jan 14 '23 at 18:12
  • Even if you do that, though, you still need to source the script instead of running it as a subprocess; the above tinkers around the edges to reduce the number of pitfalls, but it doesn't change the overall issue the question was asked about. – Charles Duffy Jan 14 '23 at 18:13

0 Answers0