

Taming non-terminating Bash processes - pstadler
https://github.com/pstadler/non-terminating-bash-processes

======
fensipens
Sorry Pädu but this smells for many reasons.. first:

    
    
         The dns-sd command is primarily intended for interactive use.  Because
         its command-line arguments and output format are subject to change,
         invoking it from a shell script will generally be fragile. Additionally,
         the asynchronous nature of DNS Service Discovery does not lend itself
         easily to script-oriented programming. For example, calls like "browse"
         never complete;
    

Second, "SIGKILL is too verbose, SIGINT is too soft".. how about SIGTERM? Its
very likely that you're doing it wrong if you need to use -KILL in your
scripts.

Third, "[1] 58181 killed ./discover-vnc.sh --- It's crucial to suppress this
line." again, if you think you must suppress this, you're doing it wrong. This
shouldn't pop up in the first place.

Fourth, what about fifos and `$!'?

Fifth, why bash? Use the sh-subset.

etc.

It's cute that you managed to solve your problem but this is nothing more than
an unreliable hack, pompously presented ("Taming non-terminating Bash
processes", "Kill the children"..)

~~~
pstadler
Thanks man, your feedback is appreciated. I'm well aware of the dirty nature
of this solution[1] but it seems to be the only way to achieve this within
context (OS X, Alfred).

[1] [https://github.com/pstadler/non-terminating-bash-
processes#c...](https://github.com/pstadler/non-terminating-bash-
processes#conclusion)

Edit: $! is not working with the distributed Bash version (currently 3.2) on
OS X. Unfortunately, dns-sd is the only utility to discover network services
on OS X. There are many projects which use the same hack involving dns-sd.

I invite you to find a better solution to this problem.

~~~
fensipens
Try something like this (untested):

    
    
      #! /bin/sh
    
      fifo=/tmp/discover-vnc.fifo
      rm -f $fifo
      mkfifo $fifo
    
      dns-sd -B _rfb._tcp >$fifo &
      pid=$!
    
      while read line; do
        case $line in *_rfb._tcp.*)
          # do something here.. then test
          # if flag=3 and break otherwise
        esac
      done <$fifo
    
      kill $pid

~~~
pstadler
Results from dns-sd are not necessarily being delivered instantly and there
might be no lines which contain this flag to check of it's the last entry.
It's also rather ugly to create a named pipe for this purpose, don't you
think?

~~~
fensipens
_there might be no lines which contain this flag_

Again, untested:

    
    
            #! /bin/sh
    
            timeout=5
            fifo=/tmp/discover-vnc.fifo
            rm -f $fifo
            mkfifo $fifo
    
            dns-sd -B _rfb._tcp >$fifo &
            pid1=$!
    
            while read line; do
              case $line in *_rfb._tcp.*)
                # do something here.. then test
                # if flag=3 and break otherwise
              esac
            done <$fifo &
            pid2=$!
    
            sleep $timeout && kill $pid1 $pid2 &
            pid3=$!
    
            wait $pid2
            kill $pid3
    

_It 's also rather ugly to create a named pipe for this purpose_

Because it creates a file in /tmp? Who cares? The alternative is bash voodoo
magic.. the same magic that gave us _shellshock_.

~~~
pstadler
_The alternative is bash voodoo magic.. the same magic that gave us
shellshock._

I love this one.

------
ttwwmm
The use of <(..) is really weird here... why not just pipe dns-sd to the while
loop?

    
    
        dns-sd | while read -r line ; do
            ...
        done
    

Sure, you won't be able to accumulate the output for the trap, but you
shouldn't _need_ to---this is stream processing!

Consider replacing the while loop with awk. This sort of thing is exactly what
awk is good at:

    
    
        BEGIN { FS = " "; count = 0; }
        NR > 5 {
            count++
            print
            if ($3 != "3") { exit; }
        }
        END { printf("%d hosts found\n", count); }
    

You could also do it with GNU sed (you'll need the q or Q command for early
exit, and that's a GNU extension---no idea if it's available on OS X).

~~~
pstadler
This will stay in the loop if there's no output or if no flag == 3 is
received.

------
fragmede
That's all well and good, but the real issue is that dns-sd is really meant to
be used from a shell script _.

It should be noted that Linux's command line program to enumerate network
services, avahi-browse, includes a '-t' flag so that terminates after dumping
service entries.

_[https://developer.apple.com/library/mac/documentation/Darwin...](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dns-
sd.1.html)

~~~
duskwuff
ITYM "really _not_ meant to be used from a shell script".

