Print all environment variables but skipping multiline variables

Viewed 630

I want to print all environment variables except certain variables.

Therefore I found a solution on stackoverflow: Bash: loop through variables containing pattern in name

while IFS='=' read -r name value; do
    if [ ! "$name" = "SOMEVAR" -a ! "$name" = "SOMEOTHERVAR" ]; then
        echo "$name=$value"
    fi
done < <(env)

However this does not work if my environment variables contain newlines, such as:

export SOMEVAR="some
text with
newlines"

With the above solution it would print:

text with=
newlines=
PWD=/home/...
...

I also tried to use null-terminated strings and multiline matching with sed:

env -0 | sed -e '{N; s@SOMEVAR.*\x0@@ ; D}' | tr '\0' '\n'

But this cuts off the output and always prints the last line of a variable with multiline content at first:

newlines
PWD=/home/...
...

Is there any way to skip multiline environment variables while printing them?

2 Answers

You almost had it, you just need to loop over the output of env -0 with a read command and null delimiter and exclude the variables using the regex operator

while read -r -d '' line; do 
    [[ ! $line =~ ^(SOMEVAR|SOMEOTHERVAR)= ]] && printf '%s\n' "$line" 
done < <(env -0)

The read command with d '' implies delimit the input on the null delimit character. The while loop runs until the last delimited line is parsed.

Also this just prints all the variables excluding the ones you want to avoid. For further processing of each of the lines, you can parse out the $line variable to split the key/value pairs and use it accordingly.

Or if your intention was to identify any variable containing a multi-line string, you can exclude that with the regex as

[[ ! $line =~ $'\n' ]] 

You may use bash builtin compgen which outputs all env variable names when used with -v option so:

compgen -v # prints all variable names

Now you can easily use this in a loop to exclude unwanted names and print rest:

while read var; do
   echo "$var=${!var}"
done < <(compgen -v | grep -vxFE '(SOMEVAR|SOMEOTHERVAR)')
Related