0

Is there any way to print all the variables declared and used within a Bash script?

For example printf "%s\n" "${FUNCNAME[@]}" will print the names of all shell functions currently in the execution call stack.

Ex: This is my script content (there must be a lot of declared variables):

#!/bin/bash

say_hello() {
    name="$1"
    echo "Hello $name"
}

my_name="Luis Daniel"
my_age="29"

say_hello "$my_name"

Then, I need to log something like this:

my_name = Luis Daniel
my_age = 29
name = Luis Daniel
  • It's unclear whether you're interested in creating that particular output using e.g. three calls to echo, or whether you're interested in a more generic solution (possibly some form of shell script debugging tool?). – Kusalananda Mar 5 at 22:18
4

The commands set or declare by themselves will print all shell variables and their values (and would additionally output function definitions). declare -p would not output function definitions but would annotate each variable with its type (e.g. -r for read-only, -a for array, etc.) The export command by itself will print environment variables (exported shell variables), as would env and printenv.

Whether the variables are used or not within the current shell session will not necessarily be detected in the output of these commands. The bash shell has a number of variables that exists in any shell session, such as RANDOM and EUID, regardless of whether these are used or not. A variable may also not be available in the current scope when declare is called, for example if it's a local variable in a function, or if it has been unset, or if it was declared in a sub-shell that is no longer active.

Would you want to see the variables created in a particular script, you would have to save the output of e.g. declare -p at the start of the script and later compare that with another invocation of the same command at the end of the script (or wherever you'd like to investigate the currently declared variables).

Example:

#!/bin/bash

tmpfile=$(mktemp)
declare -p >"$tmpfile"

say_hello() {
    name="$1"
    echo "Hello $name"
}

my_name="Luis Daniel"
my_age="29"

say_hello "$my_name"

declare -p | diff "$tmpfile" -
rm -f "$tmpfile"

Running it:

$ bash script.sh
Hello Luis Daniel
46c46,49
< declare -- _=""
---
> declare -- _="Luis Daniel"
> declare -- my_age="29"
> declare -- my_name="Luis Daniel"
> declare -- name="Luis Daniel"

Note that declaring name as a local variable in the function would, since it's not available at the second call to declare -p, produce

Hello Luis Daniel
46c46,48
< declare -- _=""
---
> declare -- _="Luis Daniel"
> declare -- my_age="29"
> declare -- my_name="Luis Daniel"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.