Reputation: 161
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
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
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
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
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
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