using wait within while loop

using wait within while loop

am 02.10.2007 10:58:24 von moonhk

Hi All

What is problem in below script ?

#!/bin/ksh
FLAG=test_bg.log

[[ -f ${FLAG} ]] && echo "remove" && rm ${FLAG}

sleep 10 && touch ${FLAG} &

PID=$!
echo PID=$PID
# while [ ! -r ${FLAG} ] || [ wait ${PID} ]
while [ wait $PID ]
do
sleep 1
done
echo "Finish"

#test_bg.ksh
remove
PID=4841696
/home/ericl6/shell/test_bg.ksh[11]: test: 0403-004 Specify a parameter
with this command.
Finish

Re: using wait within while loop

am 02.10.2007 11:20:25 von Janis Papanagnou

On 2 Okt., 10:58, moonhk wrote:
> Hi All
>
> What is problem in below script ?
>
> #!/bin/ksh
> FLAG=test_bg.log
>
> [[ -f ${FLAG} ]] && echo "remove" && rm ${FLAG}
>
> sleep 10 && touch ${FLAG} &
>
> PID=$!
> echo PID=$PID
> # while [ ! -r ${FLAG} ] || [ wait ${PID} ]
> while [ wait $PID ]

The brackets are a test "operator", they are misplaced
(see error message below); remove them.

Janis

> do
> sleep 1
> done
> echo "Finish"
>
> #test_bg.ksh
> remove
> PID=4841696
> /home/ericl6/shell/test_bg.ksh[11]: test: 0403-004 Specify a parameter
> with this command.
> Finish

Re: using wait within while loop

am 02.10.2007 11:40:02 von Pierre Gaston

moonhk wrote:
> What is problem in below script ?
>
> #!/bin/ksh
....
> sleep 10 && touch ${FLAG} &
>
> PID=$!
> echo PID=$PID
> # while [ ! -r ${FLAG} ] || [ wait ${PID} ]
> while [ wait $PID ]

Apart from the incorrect use of [ ], wait is blocking so
a while loop doesn't seem usefull.

wait does not return true when the background process
runs and false when it terminates.
It does not return until the background process terminates
and then exits with the exit status of the background process.

----
pgas@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Re: using wait within while loop

am 02.10.2007 11:57:34 von Icarus Sparry

On Tue, 02 Oct 2007 02:20:25 -0700, Janis wrote:

> On 2 Okt., 10:58, moonhk wrote:
>> Hi All
>>
>> What is problem in below script ?
>>
>> #!/bin/ksh
>> FLAG=test_bg.log
>>
>> [[ -f ${FLAG} ]] && echo "remove" && rm ${FLAG}
>>
>> sleep 10 && touch ${FLAG} &
>>
>> PID=$!
>> echo PID=$PID
>> # while [ ! -r ${FLAG} ] || [ wait ${PID} ]
>> while [ wait $PID ]
>
> The brackets are a test "operator", they are misplaced (see error
> message below); remove them.
>
> Janis
>
>> do
>> sleep 1
>> done
>> echo "Finish"
>>
>> #test_bg.ksh
>> remove
>> PID=4841696
>> /home/ericl6/shell/test_bg.ksh[11]: test: 0403-004 Specify a parameter
>> with this command.
>> Finish

I agree with Janis. However I am not sure what the OP is trying to
achieve with the while loop anyhow. The "wait" command will wait for the
specified process to finish, provided it is an immediate child of the
current shell, and return its exit status. So there are 3 cases to
consider.

1) The specified process wasn't an immediate child or had already been
waited for. In this case the wait will return a non-zero status (127 in
the case I tested). The while loop will terminate straight away.

2) The specified process is/was an immediate child and had not been
waited for, and it returns a non-zero termination status. In this case
wait will wait until the process completes, then the while loop will
terminate straight away.

3) As case 2, but the child returns a zero termination status. In this
case the wait will wait for the process to complete, then the while loop
will run, so the script will do a "sleep 1". The next time the condition
for the while is tested we will be in case 1.

Or put another way

while wait $PID
do
sleep 1
done

could be written

wait $PID && sleep 1

There is a comment
# while [ ! -r ${FLAG} ] || [ wait ${PID} ]
which suggests to me that the OP wants to break out of the loop if either
the file specified by the ${FLAG} is no longer readable (probably been
removed), or the process has exited. If my assumption is correct then the
loop should probably have been written

while [ -r ${FLAG} ] && kill -0 ${PID}

but polling like this is a much more expensive approach compared to just
using wait to wait for a child.

Re: using wait within while loop

am 04.10.2007 05:40:53 von moonhk

On 10 2 , 5 57 , Icarus Sparry wrote:
> On Tue, 02 Oct 2007 02:20:25 -0700, Janis wrote:
> > On 2 Okt., 10:58, moonhk wrote:
> >> Hi All
>
> >> What is problem in below script ?
>
> >> #!/bin/ksh
> >> FLAG=test_bg.log
>
> >> [[ -f ${FLAG} ]] && echo "remove" && rm ${FLAG}
>
> >> sleep 10 && touch ${FLAG} &
>
> >> PID=$!
> >> echo PID=$PID
> >> # while [ ! -r ${FLAG} ] || [ wait ${PID} ]
> >> while [ wait $PID ]
>
> > The brackets are a test "operator", they are misplaced (see error
> > message below); remove them.
>
> > Janis
>
> >> do
> >> sleep 1
> >> done
> >> echo "Finish"
>
> >> #test_bg.ksh
> >> remove
> >> PID=4841696
> >> /home/ericl6/shell/test_bg.ksh[11]: test: 0403-004 Specify a parameter
> >> with this command.
> >> Finish
>
> I agree with Janis. However I am not sure what the OP is trying to
> achieve with the while loop anyhow. The "wait" command will wait for the
> specified process to finish, provided it is an immediate child of the
> current shell, and return its exit status. So there are 3 cases to
> consider.
>
> 1) The specified process wasn't an immediate child or had already been
> waited for. In this case the wait will return a non-zero status (127 in
> the case I tested). The while loop will terminate straight away.
>
> 2) The specified process is/was an immediate child and had not been
> waited for, and it returns a non-zero termination status. In this case
> wait will wait until the process completes, then the while loop will
> terminate straight away.
>
> 3) As case 2, but the child returns a zero termination status. In this
> case the wait will wait for the process to complete, then the while loop
> will run, so the script will do a "sleep 1". The next time the condition
> for the while is tested we will be in case 1.
>
> Or put another way
>
> while wait $PID
> do
> sleep 1
> done
>
> could be written
>
> wait $PID && sleep 1
>
> There is a comment
> # while [ ! -r ${FLAG} ] || [ wait ${PID} ]
> which suggests to me that the OP wants to break out of the loop if either
> the file specified by the ${FLAG} is no longer readable (probably been
> removed), or the process has exited. If my assumption is correct then the
> loop should probably have been written
>
> while [ -r ${FLAG} ] && kill -0 ${PID}
>
> but polling like this is a much more expensive approach compared to just
> using wait to wait for a child.- -
>
> - -


Thank a lot . My script updated as below

REMOVE_FLAG ()
{
[[ -f ${FLAG} ]] && echo "remove ${FLAG} " && rm ${FLAG}
}

NEXT_PROCESS ()
{
echo "Part 2 NEXT PROCESS"
}

# ====
# Main
# =====
# Variable Setup
PPID=$$ # current PID
cnt=0
xcnt=2
if [ $# -gt 0 ] ; then
if [ ! -z $1 ] ; then
xcnt=$1
fi
fi
INCOMP=NO
KSHNAME=$( (basename "$0") ) # Script Name
FLAG=/tmp/${KSHNAME%%.*}_${PPID}.log
#
echo xcnt=$xcnt
REMOVE_FLAG
date
sleep 10 && touch ${FLAG} & # Start Background Process
PID=$! # Child PID
echo PPID=$PPID
echo " PID=$PID"

while [ ! -r ${FLAG} ]
do
(( cnt = cnt + 1 ))
ps -ef |grep " $PID " |grep -v grep
if [ $cnt -ge $xcnt ] ; then
touch ${FLAG}
echo "send mail.... Part I Can not finish on time"
NEXT_PROCESS
INCOMP=YES
# break ;
else
echo " sleep 1"
sleep 1
fi
done

date

if [ "${INCOMP}" = "NO" ] ; then
echo "Finish"
else
REMOVE_FLAG
fi
#