• Matheus Lozano

Bash variables - Things that you probably don't know about it

Updated: Feb 13

Let’s explore the variables scopes and types, the ways to define variables on Bash and when/where to use each one.

How to list Bash variables
List of variables with typeset

Replica: https://lozanomatheus.medium.com/8a5470887331?source=friends_link&sk=26693ca772a0c54c99d3712303560ed4

About this post

It’s mainly focused on the variable scopes, their differences, when/where to use each of them, etc. I start this post because I see there is a lot of misunderstanding/misuse of the Bash variables. It can be very confusing, complex and I hope this post will help you to know more about the Bash variables, including Bash environment variables. You can check the attributes of the variables using typeset -p.

The types

There are three types of Bash variables: Array, Integer and String. It’s possible to cast/convert the values between all of them, except string to integer (in this case, Bash will set to 0).

The Bash variables are untyped, that means you don’t have to specify types when defining a variable. The default type is string, that means if you don't specify, Bash will consider as a string. For example: im_string=1 It will be a string and not an integer im_array=(array01) It will be an array, because you’re defining it inside of a brackets

The scopes

On Bash, there are a few ways to define the variables scopes. You can find examples in the "Some ways to get/define the variables" and "Exploring the variables" sections.


Program scope

This is the most restrictive variable, it’s in a program scope ("a program in a modified environment") and is limited to that program only, once the program ends, the variable will no longer exist. It needs to initiate a sub-process. A program can be a Bash script, an application, etc. It works similar to an environment variable, but only for a sub-process.


Local variable

This is a variable defined inside of a function. It won’t be accessible between functions nor to the outside of the function. Also, can’t be defined outside of a function.


Global variable

A global variable can be accessed from the same process. That means, you can define inside/outside of a function and you’ll be able to get from any place of the current, let’s say, script. The global variables won’t be accessible by the sub-processes.


Exported variables

The exported variables are also known as environment variables. It can be accessible by the current process and by the sub-processes. Here is where things get weird, there are two scopes of exported variables. You can have an exported variable in a function scope or in a global scope.

  • Function scope: It will only be accessible in the function scope and by the sub-processes in that function.

  • Global scope: It will be accessible inside/outside of the function and can be accessed by the current process and by the sub-processes.


Environment variable

As mentioned above, environment variables and exported variables are the same things.

Some ways to get/define the variables

How to define Bash variables
Image from the internet

There are many ways to define/get the variables on Bash, these are just a few of them.


declare

Is a shell builtin command. The declare can define the types and scopes.

  • var_shortcut="value" => It’s equivalent to declare var_not_shortcut="value"

  • declare -x exported_var_func_scope="value"=> Define an exported variable in a function scope

  • declare -g global_var="I am global" => Define a variable in the global scope. It's the same as declare global_var="I am global" or just global_var="I am global" declare global_var="I am global" Will be considered as a local variable if defined inside of a function.

  • declare -p => Shows all the variables

  • declare -pi => Shows only the integer variables

  • declare -a my_array="('value01' 'value02')" => Define an array within two values

  • declare -l to_lowercase="VALUE" => Define a variable and change to lowercase

env

Is a command and available via coreutils package. It can only define environment variables in program scope (“a program in a modified environment”)

  • env => Prints the environment variables for the current process

  • env my_stricted_var="mslawson" ./initiate_project_pegasus.sh => It will define an exported variable and it will unset once the script is done

export

Is a shell builtin command. It only defines exported global variables.

  • export => Prints the exported variables

  • export exported_var="value" => Define an exported variable

local

Is a shell builtin command. It only defines local variables inside of a function.

  • local => Prints the local variables defined in the current function

  • local my_local_var="value" => Define a local variable. It must be inside of a function

typeset

Is a shell built-in command, it's a synonym for declare. It can "set/get attributes and values for shell variables and functions". The typeset -p also includes other variables that aren’t printed via declare (if not used with -p), env, etc. Some of these "extra" variables are BASHPID, BASH_SUBSHELL, RANDOM, SECONDS, etc.

  • typeset -f => Prints all the functions

  • typeset -p => Prints all the variables

  • typeset -x exp_var_func_scope="value" =>It defines an exported variable in a function scope.

Get variables from a file

On Linux/Unix, everything is a file, right? This wouldn't be different for the environment variables. There are “three” files under the /proc that you can get these variable. These files are /proc/<PID>/environ, /proc/self/environ and /proc/thread-self/environ.

Exploring the variables

The types of variables on Bash
Image from the internet

Now we know a little bit more about the variables on Linux. Let’s go to the last part of this blog, let’s explore the "map" and see some practical examples.


Variables outside the function

In this simple example, I’m showing the difference between each variable and the commands used to define them. I’m only defining variables outside of a function, then trying to read from inside and outside of a function.


You’ll see that there are not many differences in this case. This is because the variables are defined in the scripts and by default, the functions inherit all the variables.

Variables inside the function

Now it’s when the things start looking different. In this example, just two of the variables can be accessed from outside of the function. This is because one of them is a global variable and the other one is an exported global variable.


Just a reminder, the global variable can be accessed from anything in that script, but not by the sub-processes. The exported global variables means that it can be accessed by anything in that script and by the sub-processes too.

Versions

These are the versions used to write this post

  • CentOS Linux release 7.9.2009 (Docker container centos:7)

  • 4.19.121-linuxkit

  • Bash 4.2.46(2)-release

Read more


Bash Variables


typeset(1)


typeset


env(1)


declare, local, typeset


The Set Builtin


Environment Variables