Bash Environment **************** Environment Variables ===================== Local Variables --------------- Not available to child processes by default. .. code-block:: bash # setting a local variable a=apples # setting multiple local variables in one statement b=berries c=carrots d=dogs; e=elephants echo $a $b $c $d $e # None of the variables above are inherited by child processes bash -c 'echo $a $b $c $d $e' Setting, Unsetting and Testing ------------------------------ Variables can be set and unset within a shell session, and tested for conditional logic .. code-block:: bash # From a new shell test ! $a && echo 'variable a does not exit' # Setting and testing the variable a=apples test $a && echo 'variable "a" now exists' # unsetting and testing the variable, we don't include thr $ unset a test ! $a && echo 'Once again variable "a" does not exit' Exporting Variables to child processes --------------------------------------- To make a variable or a set of variables available to subshells (or sub processes), they need to be exported. .. code-block:: bash # before exporting a=apricot bash -c 'test ! $a && echo variable "a" not set in the subprocess' # after exporting export a bash -c 'echo $a' # the variable needs to be exported once, changing the value doesn't require re-exporting a=apples bash -c 'echo $a' # to un-export the variable export -n a bash -c 'test ! $a && echo variable "a" not set in the subprocess' Exporting Variables Automatically --------------------------------- To export variables using the ``export`` command explicitly, the ``set -a`` option can be used .. code-block:: bash set -a # these two variables are exported automatically a=apples b=berries set +a # these two variables are NOT exported automatically c=carrots d=durian bash -c 'echo $a $b $c $d' Exporting Variables From a file ------------------------------- ``set -a`` useful when souring environment variables from a .env file. This is the best way to export variables from a file, especially when some lines in the file are # commented, or contains other shell logic .. code-block:: bash # creating a file with 4 variable assignments echo 'a=apples' >> fruits.env echo 'b=berries' >> fruits.env echo 'c=carrots' >> fruits.env echo 'd=durian' >> fruits.env set -a # load the variables from the .env file source fruits.env rm fruits.env set +a bash -c 'echo $a $b $c $d' Passing Variables to Subprocess without exporting ------------------------------------------------- If it is desirable to pass variables that shouldn't be set in the parent, variables can be set (without exporting) before executing the subprocess. .. code-block:: bash # Variables Set and passed to subprocess a=apples b=berries bash -c 'echo $a $b' # Variables are not set in the parent (current) Shell echo $a $b Shell Expansions ================ https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html Brace Expansion --------------- Brace expansion is a mechanism by which arbitrary strings may be generated .. code-block:: bash # sequence expression over ASCII echo ``letter_{a..z}`` # sequence expression over integers echo ``number_{1..24}`` # sequence expression with an increment setting echo ``number_{1..24,2}`` echo ``software_{alpha,beta,gamma}`` Variable Expansions ------------------- Many more expansion forms on. Mostly to match on variable names. https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html ``${parameter:-word}`` If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted. .. code-block:: bash echo ${PING:-SHELL} # PONG echo ${PING2:-SHELL} # SHELL echo ${PING2:-$SHELL} # /bin/bash ``${parameter:=word}`` If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way. ``${parameter:?word}`` If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted. ``${parameter:+word}`` If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted. ``${parameter:offset}`` and ``${parameter:offset:length}`` Substring of the parameter .. code-block:: bash # We gotta use the braces in this context prefix=super echo ${prefix}man and ${prefix}woman # Treat unset variables as an error set -u echo $prefix2 echo "last exit status: $?" name=postgresql # cut the last two characters echo ${name:0:-2} Command Substitution -------------------- ``$()`` string substitution of the std out of a command. is nestable in "" and within other expansions .. code-block:: bash cd $(pwd) echo "pulse" > file_$(date +%s).log # latest Distro Kernel latest_kernel=$(ls /lib/modules -At | head -n 1) Arithmatic Substitution ----------------------- .. code-block:: bash # arithmatic in the shell v=$(( 4 - 3 )); echo $v # inside a double-quote string echo "4 - 3 is $(( 4 - 3 ))" # inside a command expansion echo $(echo $(( 4 - 3 ))) # inside all sort of Expansion and substitution expressions array=( a b c d ) echo "last element is ${array[$(( ${#array[@]} - 1 ))]}"