Você está canalizando a grep output para wc e echo $? retornaria o código de saída para wc e não grep .
Você poderia contornar o problema facilmente usando a opção -q para grep :
/etc/init.d/foo status | /bin/grep -q "up and running"; echo $?
Se a string desejada não for encontrada, grep retornará com um código de saída diferente de zero.
EDIT: Como sugerido por mr.spuratic , você poderia dizer:
/etc/init.d/foo status | /bin/grep -q "up and running" || (exit 3); echo $?
para retornar com um código de saída de 3 se a string não for encontrada.
man grep diria:
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit
immediately with zero status if any match is found, even if an
error was detected. Also see the -s or --no-messages option.
(-q is specified by POSIX.)