I have a config file which contains some ENV_VARIABLE styled variables.
This is my file. It might contain $EXAMPLES of text.
Now I want that variable replaced with a value which is saved in my actual environment variables. So I'm trying this:
export EXAMPLES=lots envsubst < file.txt > file.txt
But it doesn't work when the input file and output file are identical. The result is an empty file of size 0.
There must be a good reason for this, some bash basics that I'm not aware of? How do I achieve what I want to do, ideally without first outputting to a different file and then replacing the original file with it?
I know that I can do it easily enough with sed
, but when I discovered the envsubst
command I thought that it should be perfect for my use case, so I'd like to use that.
Basic Features of envsubst The envsubst command searches the input for pattern $VARIABLE or $ {VARIABLE}. Then, it replaces the pattern with the value of the corresponding bash variable. In contrast, a pattern that does not refer to any variable is replaced by an empty string.
So, there is no way for envsubst to accept default values for unset environment variables? According to man envsubst, envsubst will only ever replace references to environment variables in the form of $ {VAR} or $VAR. Special shell features like $ {VAR:-default} are not supported.
According to man envsubst, envsubst will only ever replace references to environment variables in the form of $ {VAR} or $VAR. Special shell features like $ {VAR:-default} are not supported. The only thing you could do is to (re)define all variables in the environment of the envsubst invocation and assign local default values, if they are missing:
of course, I can invoke envsubst from bash like the following: $ export ENV_VAR=myvalue $ envsubst < input.json > output.json $ cat output.json { "variable" : "myvalue" }
Here is the solution that I use:
originalfile="file.txt" tmpfile=$(mktemp) cp --attributes-only --preserve $originalfile $tmpfile cat $originalfile | envsubst > $tmpfile && mv $tmpfile $originalfile
Be careful with other solutions that do not use a temporary file. Pipes are asynchronous, so the file will occasionally be read after it has already been truncated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With