I've got a systemd environment file that looks like this:
```
foo=bar
```
I need to read this file and export the variables in Bash. The challenge is that the right-hand side of the assignments can have special characters like `$`, `"`, or `'`, and I want to retain them as they are, just like systemd does. Any suggestions on how to achieve this?
2 Answers
You could source the file directly and just handle any edge cases manually. That's pretty much what systemd does with these files, so it’d work fine if you set it up in a standard way.
You can read the file line by line and split each line on the `=`. Here's a sample code snippet:
```bash
while read -r line || [ "$line" ]; do
case $line in
*=*) : ;;
#*|*) continue ;;
esac
varname=${line%%=*}
value=${line#*=}
case $varname in
""|[^A-Za-z_]*|*[^0-9A-Za-z_]*) continue
esac
export "$varname=$value"
done < file.env
```
Just a heads up: `read` will trim whitespace from the beginning and end of lines, so if your variables have trailing spaces, they'll get lost with this method. Another approach that keeps leading whitespace is:
```bash
while IFS= read -r line || [[ $line ]]; do
if [[ $line =~ ^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)=(.*) ]]; then
export "${BASH_REMATCH[1]}=${BASH_REMATCH[2]}"
fi
done < file.env
```
This method is untested, though!
Just to clarify, the `|| [ "$line" ]` part is important if your file doesn't end with a newline. If it doesn't, it could have issues if it has Windows newline characters, so make sure to fix those first before running the script.
Thanks a lot for the help!

Unfortunately, I'd need it to be fully automated for this situation. The values can be quite complex, like: `f=a$~>#"z`, and I need them processed exactly as they are.