Simple background process question in bash
I am using BASH and I am calling a couple of functions which update a couple of variables. These functions take too long to complete so I was thinking running all of the functions in the background so that they can be running simultaneously. This is a basic example of what i am asking.
#/bin/bash
func1()
{
var1="one"
}
func2()
{
var2="two"
}
func3()
{
var3="three"
}
echo "Right now this is what i am doing"
func1 &
func2 &
func3 &
wait
echo "The variables are $var1 $var2 $var3"
echo "But the variables are empty.
echo "Hence, I am assuming开发者_如何学JAVA that they are not accessible outside of the function"
I feel like I am missing something very silly. Of course if I don't run the functions in the background, they show the correct variables. Thank you in advance.
If you really need to do it a hack would be to have your functions print out bash code, which you could then capture somehow and evaluate.
Pretty sure the easiest way would just be to have your functions output the code to a temp file and then source that file at the end. So you would change the functions to be like:
func1(){
echo "var1=one"
}
then at the end do something like:
TEMPFILE=`mktemp`
func1 >> $TEMPFILE &
func2 >> $TEMPFILE &
func3 >> $TEMPFILE &
wait
source $TEMPFILE
rm $TEMPFILE
echo "$var1 $var2 $var3"
If the functions themselves are printing output then you might have to do something like export the variable holding the name of the temp file and then have the redirect in the function, viz:
export TEMPFILE=`mktemp`
func1(){
echo "var1=one" >> $TEMPFILE
}
don't forget to delete temp files...
NOTE: There is probably a much better way.
If you run something in the background, it runs as a separate child process, with its own environment.
It cannot affect the environment of the current process (the parent process of those subshells).
So it's not so much that the variables aren't available outside of the function as they're not available outside of the process. The function is irrelevant since, if you run them in the foreground (without the &
), the variables are set just fine.
Hmm try this:
First off, instead of var3="value"
, use echo -n value > .var3
and write the value to a file. The dot before the name will make it "hidden", and -n
stops echo from putting a newline after it.
then at the end, instead of echo "values are $var1 $var2 $var3"
do echo "values are $(cat .var1) $(cat .var2) $(cat .var3)"
. The cat
command prints the file content to standard out.
=-)
P.S. You can also use "named pipes". use mkfifo
to make a named pipe. One thing though, when you echo to a named pipe, you must start that as a job, or your script will hang till you read the contents [with cat]. So: echo val > .named_pipe&
精彩评论