Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash variable scope

Tags:

scope

bash

pipe

People also ask

Do bash variables have scope?

Variable Scope of Bash FunctionsBy default, every variable has a global scope that means it is visible everywhere in the script. You can also create a variable as a local variable. When you declare a local variable within the function body, it is only visible within that function.

How do you set a global variable in bash?

The easiest way to set environment variables in Bash is to use the “export” keyword followed by the variable name, an equal sign and the value to be assigned to the environment variable.

What is $_ in bash?

$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.

What is the scope and lifetime of a global shell variable in Linux?

A Global Variable in the program is a variable defined outside the subroutine or function. It has a global scope means it holds its value throughout the lifetime of the program. Hence, it can be accessed throughout the program by any function defined within the program, unless it is shadowed.


Because you're piping into the while loop, a sub-shell is created to run the while loop.

Now this child process has its own copy of the environment and can't pass any variables back to its parent (as in any unix process).

Therefore you'll need to restructure so that you're not piping into the loop. Alternatively you could run in a function, for example, and echo the value you want returned from the sub-process.

http://tldp.org/LDP/abs/html/subshells.html#SUBSHELL


The problem is that processes put together with a pipe are executed in subshells (and therefore have their own environment). Whatever happens within the while does not affect anything outside of the pipe.

Your specific example can be solved by rewriting the pipe to

while ... do ... done <<< "$OUTPUT"

or perhaps

while ... do ... done < <(echo "$OUTPUT")

This should work as well (because echo and while are in same subshell):

#!/bin/bash
cat /tmp/randomFile | (while read line
do
    LINE="$LINE $line"
done && echo $LINE )

One more option:

#!/bin/bash
cat /some/file | while read line
do
  var="abc"
  echo $var | xsel -i -p  # redirect stdin to the X primary selection
done
var=$(xsel -o -p)  # redirect back to stdout
echo $var

EDIT: Here, xsel is a requirement (install it). Alternatively, you can use xclip: xclip -i -selection clipboard instead of xsel -i -p


 #!/bin/bash
 OUTPUT="name1 ip ip status"
+export XCODE=0;
 if [ -z "$OUTPUT" ]
----

                     echo "CRIT: $NAME - $STATUS"
-                    echo $((++XCODE))
+                    export XCODE=$(( $XCODE + 1 ))
             else

echo $XCODE

see if those changes help


Another option is to output the results into a file from the subshell and then read it in the parent shell. something like

#!/bin/bash
EXPORTFILE=/tmp/exportfile${RANDOM}
cat /tmp/randomFile | while read line
do
    LINE="$LINE $line"
    echo $LINE > $EXPORTFILE
done
LINE=$(cat $EXPORTFILE)

I got around this when I was making my own little du:

ls -l | sed '/total/d ; s/  */\t/g' | cut -f 5 | 
( SUM=0; while read SIZE; do SUM=$(($SUM+$SIZE)); done; echo "$(($SUM/1024/1024/1024))GB" )

The point is that I make a subshell with ( ) containing my SUM variable and the while, but I pipe into the whole ( ) instead of into the while itself, which avoids the gotcha.