Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Waiting for a process without using pid



On 09/19/2010 01:11 AM, Bart Schaefer wrote:
> On Sep 18, 11:51pm, Anonymous bin Ich wrote:
> } Subject: Re: Waiting for a process without using pid
> }
> } On 09/16/2010 07:56 PM, Bart Schaefer wrote:
> }>  On Sep 16,  4:09pm, Anonymous bin ich wrote:
> }>  }
> }>  } I am trying to write a 'timeout' script, which will take 2 commands
> }>  } and exit after whichever one exits first. Is there a way to do it
> }>  } without using pid or polling?
> }>
> } But I see that job2 is still running at the end, just the script having
> } this code forks at then kills both its instances.
>
> If I understand that correctly, what you want is for the control script
> AND both of its children to exit all at the same time, whenever at least
> one of the children has exited?
>
> That wasn't clear before.
>
> Also after a bit of thought it's really not necessary to kill the
> coprocess, you can do all the synchronization with I/O; and it's a
> better solution to start the coprocess and set up the trap first,
> rather than starting the background jobs first.
>
> cat<<-\ENDOFA>a.sh
> 	#!/usr/bin/zsh
>
> 	coproc read -E
> 	trap "print Waking coprocess; print -p Woken" CHLD
>
> 	setopt HUP
> 	./b.sh 10&
> 	echo $!
> 	./b.sh 20&
> 	echo $!
>
> 	read -p -E
> 	print "Finished"
> 	kill -HUP -$$
>
> 	# Never get here
> 	exit 0
> ENDOFA
> cat<<-\ENDOFB>b.sh
> 	#!/usr/bin/zsh
> 	trap "print HUP $1 in $$; exit 0" HUP
> 	print start $1 in $$
> 	sleep $1
> 	print stop $1 in $$
> ENDOFB
>
> The trap in b.sh is just so you can see what's going on.
>
> If the parent doesn't need to do anything after the first child exits,
> you can avoid the coprocess entirely by having both children kill the
> parent:
>
> cat<<-\ENDOFA>a.sh
> 	#!/bin/zsh
>
> 	setopt HUP
>
> 	repeat 2 {
> 		: $RANDOM to prime the number generator
> 		{ ./b.sh $((RANDOM%10+10)); kill -HUP -$$ }&
> 	}
>
> 	wait
> ENDOFA
Ok, I have made some modifications, and I am now confused :(
Three output are given here. Is there a race condition somewhere?

% cat child.sh
#!/bin/sh
if [ $# -gt 0 ]; then
     gotsig=0
     trap "exitfunc" INT HUP TERM
     exitfunc () {
         echo $$: Got sig...
         gotsig=1
     }
     echo $$: Sleeping for $1 seconds
     sleep $1 &
     pid=$!
     wait
     if [ $gotsig -ne 0 ]; then
         echo $$: Stopping sleep in $pid for $1 seconds
         kill $pid
     else
         echo $$: Slept for $1 seconds
     fi
else
     echo No args
     exit 1;
fi

cat parent.sh
#!/usr/bin/zsh

coproc read -E
trap "print Waking coprocess; print -p Woken" CHLD

setopt HUP
./child.sh 1 &
echo $!
./child.sh 5 &
echo $!

read -p -E
print "Finishing $$"
kill -HUP -$$

# Never get here
exit 0

% ./parent.sh
4369
4370
4369: Sleeping for 1 seconds
4370: Sleeping for 5 seconds
4369: Slept for 1 seconds
Waking coprocess
Woken
Finishing 4367
4370: Got sig...
4370: Stopping sleep in 4372 for 5 seconds
% ./parent.sh
4375
4376
4375: Sleeping for 1 seconds
4376: Sleeping for 5 seconds
4375: Slept for 1 seconds
Waking coprocess
Woken
Finishing 4373
4376: Got sig...
4376: Stopping sleep in 4378 for 5 seconds
kill: 1: No such process
% ./parent.sh
4381
4382
4381: Sleeping for 1 seconds
4382: Sleeping for 5 seconds
4381: Slept for 1 seconds
Waking coprocess
Woken
Finishing 4379
4382: Got sig...
4382: Stopping sleep in 4384 for 5 seconds
%

PS: My original aim was to have both childs killed whenever SIGCHLD is
received, and parent should continue to run. But I think I can manage
that if this problem goes away...



Messages sorted by: Reverse Date, Date, Thread, Author