Pass return value of a function in background process

Hi,
I have created a function f1 defined in script A.sh .I have called this function in background . But I want to use its return value for another function f2 in script A.sh.
I tried declaring it as a global variable, yet it always returns the status as 0. Is there any way with which I can get the values from function f1 and use it in function f2 with function f1 running in background ??

template of my script:


STATUS=0; export STATUS

f1()
{
if<>
then
   STATUS=1
else
   STATUS=2
fi
}


f2()
{
f1 >output.txt &
echo "STATUS $STATUS";
}

f2

You can't pass variables from a subprocess back to the calling process. You can intercept the output and assign it to a variable.

What sense does it make to run a process in background and then wait for its status (and/or output)?

Its because the function f2 is function I have used to display status of the operations going on in function f1.
Can you explain "You can intercept the output and assing it to a variable."
How can we do the above?

Use "command substitution" like

f1(){ echo 1; }
STATUS=$(f1)
echo $STATUS
1
1 Like

You are bringing together a few unrelated issues:

(1) While a shell function can modify a global shell variable, this works of course only if they run in the same process, because shell programming - at least those shells I know - don't have the concept of variables which are shared between processes.

(2) Your code shows that you start a child process, but you never wait for it, so even if there would be a possibility for the child process to pass information back to the parent, there is no point in the program you posted, where you would fetch this information.

(3) If the value you want to return from the function, is a small number (between 0 and 127), you can return it as the exit code of the invoked function. Of course, you still need to fetch it. You would do this by explicitly waiting for the function to finish using the wait command. This command returns the exit status of the child. Have a look at the description of your command the man page of your shell.

And, if you wait for a background process, then it's the same as if you run it in the foreground.
So, in general the answer is "no, you cannot get a result from a background process".
--
The exit status of a function is the one from the last process.

f1(){
  ls "$@"
}
f1 "/dir"; echo "exit status $?"

If you want ta return the status from a previous command then use the following

f1(){
ls "$@"
save_exit=$?
echo "another command"
return $save_exit
}

This is only true, if you need the result immediately after the background process has started, but in this case, it is pointless anyway to run the function as a child process. I guess the OP really wanted to do some work in between, for why else should he have started the background process.

Now thinking of this posting again, I believe that, for giving a good advice, we really would need to know what exactly the OP wanted to achieve.

If you need really put something to do in background, then do something (parallel) and after that wait the child process to end, solution could be something like:

child()
{
  parentfile=$1

  do_something
  stat=$?

  echo "mypid=$$
           mystat=$stat" > $parentfile
}


#########
# MAIN

# file to use get answer from child process
childfile=$$.child.txt

# start child
child $childfile >/dev/null 2>&1  &
# save child process PID
CHILDPID=$!

do_something

# wait child process to end
wait $CHILDPID

# source childfile answer
. $childfile
# and destroy it
rm -f $childfile 2>/dev/null 

# use values
echo "child pid=$mypid"
echo "stat=$mystat"

Other method is to use event methods to communicate between process (trap + kill). Use file to move values between process. I like more event methods. There are not any shared variables. Of course you can use also named pipes between process. Source file is so easy.