I have a program (prog) that accepts a parameter in order to execute some internal loop grabbing memory in each iteration. I'm using top to monitor the memory usage and to produce an output.
Thus I need the program's pid as a parameter to top.
I capture pid using myPID=$!.
I'm also checking if the program returns an error code in order to stop the script's execution.
Now using & myPID always equals to 0 even if the program returns an error. Removing & error capture works fine but I have no pid.
Is there any work around in order to have error trapping and pid at the same time?
#!/bin/sh
./prog $1 &
myPID=$!
if [ $? -ne 0 ]
then
echo "error captured"
exit 1
fi
echo $myPID
top -p $myPID -b -d 1 -n $1 | sed -n '8~10p' | awk '{print $5}' > res.txt
Yes, but you cannot access the exit status of the process untill it finishes (sort of obvious really).
So, what you probably want to do is sleep for a second or so and then ensure your program started properly (eg use kill -0 $myPID or check directory /proc/$myPID exists) then do your top command and finally wait $myPID to get it's exist status.
Imho the "-p" parameter to "top" is not the PID.
I can't claim to know every version of "top" but please do check your "man top" and prove me wrong.
In order to suggest a suitable "ps" command we'd need to know what Operating System and version you are running.
Having re-read your post you may need to encapsulate the the process in a script (albeit backgrounded) which checks the exit status of the actual program you are running in background.
In you current script the exit status $? is that of the background command "&". It would be hard to not get a value in $! (background PID) in these circumstances. As ChublerXL implies, check whether the process disappears quickly which would suggest failure.
Important. Backgrounding a task takes real time. On a modern multi-processor system it is prudent to run a short "sleep" command to give the process time to start or fail before monitoring it.
#!/bin/sh
./prog $1 &
myPID=$!
sleep 1
kill -0 $myPID
if [ $? -ne 0 ] ; then
echo 'process terminated'
exit
fi
top -p $myPID -b -d 1 -n $1 | sed -n '8~10p' | awk '{print $5}' > res.txt
It runs smoothly :).
Just a slight drawback as prog should iterate $1 times grabbing some memory each time. Between each iteration it sleeps 1 sec. As my script sleeps for 1 sec I monitor $1-1 iterations than $1.