Como você alimenta o shell chamado por su(1) de um script, $! é interpretado pelo script que chama su(1) . A maneira de evitar isso é escapar de $! , então $! é alimentado para o shell invocado por su(1) e não o script de chamada:
if [ $UID -eq 0 ]; then
su myuser <<EOF
sleep 30 &
echo \$! >mypid.pid
EOF
fi