I'm working on a script in which I'm trying to have two concurrent timers within the same process. In the following example, I'm trying to update the ip address every 60 seconds, while outputting the ip every 5 seconds:

while true; do
  ip=$(curl -4 -sf ifconfig.co)
  sleep 60
done &

while true; do
  echo $ip
  sleep 5

The problem here is that the first while loop creates a subprocess and thus does not share the ip address variable. But if I remove the &, the script will never get to the second loop.

I could potentially integrate both loops into one, but I'm wondering if there isn't a better way to have these two loops run concurrently within the same process

  • If you're only updating the IP address variable every 60 seconds, why bother printing it every 5?
    – roaima
    Aug 3 '20 at 12:25
  • 1
    it's just an example, the $ip variable can be changed from outside of these loops as well
    – Subbeh
    Aug 3 '20 at 12:28

No; bash does not support concurrency or multi-threading that way. Subshells also do not communicate with each others variables.

It is possible to pass information from one subshell to another using FIFOs or temporary files.

As an example (just to get you going):

mkfifo hoppa

while true; do
  curl -4 -sf ifconfig.co >> hoppa
  sleep 60
done &

while : ; do
    read -t1 d <> hoppa
    if [ "$d" != "" ] ; then
        echo '+'
        echo -n '.'
    echo $ipread
    sleep 5
done &
  • Thanks, never heard of FIFOs but I will look into it
    – Subbeh
    Aug 3 '20 at 12:41
  • 1
    @Subbeh FIFOs, in this context aka "named pipes". There is no possibility to fork() a shell and thus duplicate its filedescriptors, so unnamed pipes are not possible. Aug 3 '20 at 13:04
  • Surely | creates an un-named pipe? You could put each while loop in a shell function and then ( curlFunc ) | ( showFunc ). Aug 3 '20 at 15:44
  • Named Pipes are fairly magic. Not obvious from the documentation, but a single fifo can have multiple writers and readers. So a script can add new background processes that send it stuff on an existing pipe and then exit. The pipe works atomically (up to a certain size) so inputs do not get mixed up. The reader can open the pipe for writing itself to avoid getting EOF, even if all writers end. Aug 4 '20 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.