Bash Script Variable Scope Issue

Bash variable scope

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

while loop with global variable scope issue in shell script with psql

Your while loop executes in a subshell because it is executed as part of the pipeline. You can avoid it by using lastpipe or placing the psql command inside process substitution.

#/bin/bash
shopt -s lastpipe
...

Or

res_count=0

while read dCount ; do
res_count=$dCount
done < <(psql -h "$db_host" -U "$db_user" -d "$db_name" -At \
-c "select count(id) as dCount from abc"
--no-password --field-separator ' ')

echo "$res_count"

As a side note, quote your variables properly.

Bash Script Variable Scope Issue

The reason that this is not working is actually the UUOC. In bash, the right side of a pipeline is ran inside of a sub-shell. Any variables set inside of a sub shell will not be set in the parent shell. To fix this, use redirection instead of a pipeline:

username="hello"
password="3333"

function login {
# 1 - Username
# 2 - Password
match=0
while read x y _; do
if [ "${x}" == "${1}" ] && [ "${y}" == "${2}" ]; then
echo "match"
match=1
echo $match
break
fi
done < LoginsMaintMenu.txt
echo $match
return $match
}

echo $username $password
if login "${username}" "${password}"; then
echo "FAIL"
else
echo "success"
fi

bash variable scope issue with function fork (&)

f1 and f2 will be separate processes thus having separate address space from the main process. Therefore your loop will be infinite.

You need to use wait instead.

i.e.

change

until [[ "$f1done" == "true" && "$f2done" == "true" ]]; do
echo "$f1done $f2done...";
sleep 3;
done

to

wait;
wait;

Bash local variable scope best practice

the best practice to follow

Check your scripts with https://shellcheck.net .

Quote variable expansions. Don't $var, do "$var". https://mywiki.wooledge.org/Quotes

Prefer to use lowercase variables for script local variables A=true. Prefer to use upper case and very unique names for exported variables.

Do not use function name(). Use name(). https://wiki.bash-hackers.org/scripting/obsolete

Document the usage of global variables a=true. Or add local before using variables local a; then a=true. https://google.github.io/styleguide/shellguide.html#s4.2-function-comments

scope best practice

Generally, use the smallest scope possible. Keep stuff close to each other. Put local close to the variable usage. (This is like the rule from C or C++, to define a variable close to its usage, but unlike in C or C++, in shell declaration and assignment should be on separate lines).

Note that your examples are not the same. In the case variable A (or a) is an empty string, the first version will print an empty line (the local animal variable is empty), the second version will print the value of the global variable animal (there was no local). Although the scope should be as smallest, animal is used outside of if - so local should also be outside.

Variable scope for bash shell scripts and functions in the script

You can try something like

global1=0
global2=0
start_read=true

function testfunc {
global1=9999
global2=1111
echo "in testfunc"
echo $global1
echo $global2
duration=something
}

file1=whocares
file2=whocares2

for line in `cat $file1`
do
for i in `grep -P "\w+ stream" $file2 | grep "$line"` # possible but unlikely problem spot
do
end=$(echo $i | cut -d ' ' -f 1-4 | cut -d ',' -f 1) # possible but unlikely spot
testfunc $end # more likely problem spot
done
done

echo "global1 = $global1"
echo "global2 = $global2"


Related Topics



Leave a reply



Submit