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
Jenkins to Run Maven Build on Linux or Windows
Why Does Docker Prompt "Permission Denied" When Backing Up the Data Volume
No Error on Xcb_Grab_Key But Event Loop Not Catching (Global Hotkey)
Ldconfig Only Links Files Starting with Lib*
How Many Instructions Does Linux Kernel Need in Order to Handle an Interrupt on an Arm Cortex A9
Fatal: Git Was Built Without Support for Git-Add--Interactive (No_Perl=1)
Why /Lib32/Libc.So.6 Has Two "Fopen" Symbol in It
Getting Current Working Directory Within Kernel Code
Sync Two Computers Going Through a Bridge with Rsync
What Is the Meaning of !#:* !#:1- in a Bash Command
Cannot Make Bash Script Work from Cloud-Init
Communicating Between a Parent and Its Children
I.Mx35 Suspend CPU and Ddr2 from Iram
Icudt Error While Installing Stringi Package from R in Linux Offline
How to Concatenate Files with the Same Prefix (And Many Prefixes)
How to Enable Evp Functions in Openssl
The New Line Characted in the String Constant Isn't Being Recognized by Nasm