How to list variables declared in script in bash?

Viewed 99268

In my script in bash, there are lot of variables, and I have to make something to save them to file. My question is how to list all variables declared in my script and get list like this:

VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi
15 Answers
for i in _ {a..z} {A..Z}; do eval "echo \${!$i@}" ; done | xargs printf "%s\n"

This must print all shell variables names. You can get a list before and after sourcing your file just like with "set" to diff which variables are new (as explained in the other answers). But keep in mind such filtering with diff can filter out some variables that you need but were present before sourcing your file.

In your case, if you know your variables' names start with "VARIABLE", then you can source your script and do:

for var in ${!VARIABLE@}; do
   printf "%s%q\n" "$var=" "${!var}"
done

UPDATE: For pure BASH solution (no external commands used):

for i in _ {a..z} {A..Z}; do
   for var in `eval echo "\\${!$i@}"`; do
      echo $var
      # you can test if $var matches some criteria and put it in the file or ignore
   done 
done

A little late to the party, but here's another suggestion:

#!/bin/bash

set_before=$( set -o posix; set | sed -e '/^_=*/d' )

# create/set some variables
VARIABLE1=a
VARIABLE2=b
VARIABLE3=c

set_after=$( set -o posix; unset set_before; set | sed -e '/^_=/d' )
diff  <(echo "$set_before") <(echo "$set_after") | sed -e 's/^> //' -e '/^[[:digit:]].*/d'

The diff+sed pipeline command line outputs all script-defined variables in the desired format (as specified in the OP's post):

VARIABLE1=a
VARIABLE2=b
VARIABLE3=c

If you're only concerned with printing a list of variables with static values (i.e. expansion doesn't work in this case) then another option would be to add start and end markers to your file that tell you where your block of static variable definitions is, e.g.

#!/bin/bash

# some code

# region variables
VAR1=FOO
VAR2=BAR
# endregion

# more code

Then you can just print that part of the file.

Here's something I whipped up for that:

function show_configuration() {
   local START_LINE=$(( $(< "$0" grep -m 1 -n "region variables" | cut -d: -f1) + 1 ))
   local END_LINE=$(( $(< "$0" grep -m 1 -n "endregion" | cut -d: -f1) - 1 ))
   < "$0" awk "${START_LINE} <= NR && NR <= ${END_LINE}"
}

First, note that the block of variables resides in the same file this function is in, so I can use $0 to access the contents of the file.

I use "region" markers to separate different regions of code. So I simply grep for the "variable" region marker (first match: grep -m 1) and let grep prefix the line number (grep -n). Then I have to cut the line number from the match output (splitting on :). Lastly, add or subtract 1 because I don't want the markers to be part of the output.

Now, to print that range of the file I use awk with line number conditions.

The printenv command:

printenv prints all environment variables along with their values.

Good Luck...

Simple way to do this is to use bash strict mode by setting system environment variables before running your script and to use diff to only sort the ones of your script :

# Add this line at the top of your script :
set > /tmp/old_vars.log

# Add this line at the end of your script :
set > /tmp/new_vars.log

# Alternatively you can remove unwanted variables with grep (e.g., passwords) :
set | grep -v "PASSWORD1=\|PASSWORD2=\|PASSWORD3=" > /tmp/new_vars.log

# Now you can compare to sort variables of your script :
diff /tmp/old_vars.log /tmp/new_vars.log | grep "^>" > /tmp/script_vars.log

You can now retrieve variables of your script in /tmp/script_vars.log. Or at least something based on that!

TL;DR

With: typeset -m <GLOBPATH>

$ VARIABLE1=abc
$ VARIABLE2=def
$ VARIABLE3=ghi
$ noglob typeset -m VARIABLE*
VARIABLE1=abc
VARIABLE2=def
VARIABLE3=ghi

¹ documentation for typeset can be found in man zshbuiltins, or man zshall.

Related