DaWe4444
DaWe4444

Reputation: 161

How to pass VAR from child script to parent's script running loop

I'm thinking how to solve this functionality on the following example:

#!/bin/bash

. script.sh &

while [ "$VAR" != "OK" ];
do
    echo -e "Waiting..."
    sleep 1
done

script.sh

#!/bin/bash
export VAR=OK

As the while loop runs in subshell of it's parent shell, it will never finishes as will never get the sourced script.sh export VAR=OK.

Any ideas how to pass the VAR value to the while loop ?

NOTE: I need to run the script.sh in background.

Thanks !

Upvotes: 2

Views: 1825

Answers (5)

SachinPatil4991
SachinPatil4991

Reputation: 774

You can achieve this using process Substitution

#!/bin/bash

VAR=$(. script.sh &)

while [ "$VAR" != "OK" ];
do
    echo -e "Waiting..."
    sleep 1
done

script.sh

$VAR=OK
echo $VAR

Upvotes: 0

HardcoreHenry
HardcoreHenry

Reputation: 6387

This should do what you want:

child:

sleep 1
echo blah >> $varfile

parent:

#make sure varfile exists and is empty..
echo > varfile

#run script in background
./script.sh &

# wait for some output:
VAR=$( ( tail -f varfile & )  | sed "/.*$/q")
echo >> varfile;

Just to explain a bit of trickery here:

tail -f is used to capture the output. This call does not terminate when it hits the end of the file, but instead, sits and waits for more to be written to the file (which is what you want... at first...). When it receives a complete line, it will output it, and then wait for then next line. The trick is it does not terminate under normal circumstances. Instead, it will continue to run until either someone does a ctrl-c or it detects a broken pipe. This must be pushed to be a background task, otherwise the command in the script would never terminate. It's output is piped into sed. sed on the other hand will terminate when it receives a valid end of input (due to the $ in the pattern), and when it does, execution of the script continues. But notice that task is still running at this point, and will continue to run until it attempts to push something to the now-broken pipe. To prevent it from running indefinitely, we output something to it after sed terminates, at which point it realizes the pipe is broken, and terminates.

Upvotes: 1

joshbooks
joshbooks

Reputation: 489

Unix/Linux systems have great support for inter-process communication. In this case I think what you're looking for is signalling. For instance you could do something like this:

foo &
FOO_PID=$!
# do other stuff
kill $FOO_PID

if it's important that the loop complete before the process exits you can trap that signal and set VAR=OK when you receive that signal

Upvotes: 0

UtLox
UtLox

Reputation: 4154

child

#!/bin/bash
sleep 2                   # wait 2 seconds
echo "OK"

parent

#!/bin/bash
answer=$(mktemp)          # create a tempfile
./script.sh & >$answer    # start script in background, output in tempfile
wait $!                   # wait for script.sh finished
var=$(cat $answer)        # read anwser in variable 
echo $var                 # echo anwser
rm $answer                # cleanup - remove tempfile

Upvotes: 1

Adam vonNieda
Adam vonNieda

Reputation: 1745

parent.sh

#!/bin/bash

while :
do
   if [ -e /tmp/var_file ]; then
      VAR=$(cat /tmp/var_file)
      echo "VAR is $VAR"
      rm -f /tmp/var_file
   fi
   sleep 1
done

child.sh

#!/bin/bash

echo "SUCCESS" > /tmp/var_file

Upvotes: -1

Related Questions