It's not safe.
Assume three copies of your script (A, B and C) are started simultaneously and /tmp/test.pid does not exist initially.
Let A and B complete the initial statements of the script:
PIDFILE=/tmp/test.pid
flag=$PIDFILE.flag
touch $flag
if [ -f $PIDFILE ]; then
ps | grep -qE '^\s*'$(cat $PIDFILE) && exit
fi
Switch to A and let it run two more statements:
echo $$ > $PIDFILE
rm $flag || exit
This succeeds; $PIDFILE now contains A's PID.
Switch over to B and let it run the same statements. rm fails and so B exits, but $PIDFILE now contains B's PID.
Switch over to C. C has just started running, so the first thing it does is to recreate $flag:
PIDFILE=/tmp/test.pid
flag=$PIDFILE.flag
touch $flag
Now comes the PID check:
if [ -f $PIDFILE ]; then
ps | grep -qE '^\s*'$(cat $PIDFILE) && exit
fi
This passes because $PIDFILE contains B's PID, but B is no longer running.
Now we get to
echo $$ > $PIDFILE
rm $flag || exit
This also passes because C has just recreated the $flag file.
Now we have both A and C running, racing against each other to overwrite $PIDFILE again.
Apart from that there's also a "false positive" problem:
if [ -f $PIDFILE ]; then
ps | grep -qE '^\s*'$(cat $PIDFILE) && exit
fi
You might have a stale $PIDFILE, but the PID it contains has been reused for another process. In that case you don't get a race (and too many instances of your script), but a denial of service (too few instances of your script: 0). Your script will see the running process that just happens to have the "wrong" PID and exit.