оператор if всегда оценивается как TRUE - PullRequest
7 голосов
/ 11 ноября 2009

Есть ли какая-либо причина, по которой этот скрипт всегда возвращает "выполняется", независимо от того, запущен или остановлен мой процесс?

if ps ax | grep -v grep | grep "processName" > /dev/null
then
   echo $"running"
else
   echo $"not running"
fi

Большое спасибо

ОБНОВЛЕНИЕ: Я добавляю полный пример своего сценария, возможно, что-то не так в другом месте.

case "$1" in
  start)
    # Start daemons.

    echo -n $"Starting daemon: "
    ;;

  stop)
    # Stop daemons.
    echo -n $"Shutting down: "
    echo
    ;;
  status)
    pgrep -f "ProcessName" > /dev/null
    if [ $? -eq 0 ]; then
        echo $"ProcessName is running"
    else
        echo $"ProcessName is not running"
    fi
    ;;
  restart)
    $0 stop
    $0 start
    ;;

  *)
    echo $"Usage: $0 {start|stop|status|restart}"
    exit 1
esac

ОБНОВЛЕНИЕ 2:

[user@dev init.d]# pgrep -f "MyProcess" > /dev/null
[user@dev init.d]# echo $?
0
[user@dev init.d]# service MyProcess stop
Shutting down MyProcess: Terminated
[user@dev init.d]# pgrep -f "MyProcess" > /dev/null
[user@dev init.d]# echo $?
1

Но if [ $? -eq 0 ]; then кажется ИСТИННЫМ все время

Ответы [ 4 ]

16 голосов
/ 11 ноября 2009

Попробуйте вместо этого:

ps aux | grep -q "[p]rocessName"
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi

Квадратные скобки вокруг первой буквы processName означают, что не требуется "grep -v grep", а -q означает, что нам не нужен канал для / dev / null

$? дает код возврата предыдущей выполненной команды. Следовательно, тестирование, если оно было 0, показало бы, нашел ли "grep" то, что искал.

Обновление

Если имя вашего процесса действительно короткое (скажем, "чашка"), вы можете получить ложный положительный результат, так как оно может совпадать и с другими процессами (скажем, "cupsd"). Вы можете преодолеть это, используя grep для сопоставления целых слов - добавьте флаг "-w".

Не то чтобы эта техника не идеальна. Вы можете в конечном итоге сопоставить записи в полях имени пользователя / даты. Если это произойдет, посмотрите «man ps» и будьте более разборчивы с тем, что вы печатаете, прежде чем делать grep. Также можно предварительно отфильтровать вывод с помощью awk, чтобы извлечь только столбец с именем процесса / cmd. Например:

ps aux | awk '{print $11}' | grep -q -w "[p]rocessName"
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi

Обновление 2

Вы также можете использовать pgrep, как предложено в ответе ниже.

Для действительно коротких имен процессов вы можете указать границы слов (\ b) до и после имени процесса, чтобы предотвратить совпадение (как описано выше)

pgrep "\bprocname\b" > /dev/null
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi

Обновление 3

Из обновленного вопроса я вижу, что вы запускаете его из сценария инициализации. Всегда существует опасность совпадения pgrep с самим сценарием. Попробуйте:

pgrep Processname | grep -q -v $$
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi

Это исключает PID скрипта из совпадений pgrep.

Обновление 4

(окончательное обновление? Пальцы скрещены)

Если скрипт init запускается с помощью команды "service", то нам также необходимо отфильтровать родительский PID. Как насчет:

pgrep Processname | grep -v $$ | grep -q -v $PPID
if [ $? -eq 0 ]; then
    echo "running"
else
    echo "not running"
fi
2 голосов
/ 11 ноября 2009

Вероятно, потому что grep "processName" находит себя. Вчера я обнаружил эту же проблему, за исключением того, что я xarg показывал результаты kill ...

В качестве альтернативы вы можете попробовать команду pgrep вместо строки ps и различных grep s:

sd@camel:~$ pgrep bash
415
3477
sd@camel:~$ echo $?
0
sd@camel:~$ pgrep arf
sd@camel:~$ echo $?
1
1 голос
/ 11 ноября 2009

G'day,

В сторону, вместо

ps ax | grep -v grep | grep "processName"

Попробуйте сделать

ps ax | grep "[p]rocessName"

ps перечисляет функцию grep, потому что она видит строку "grep processName" в списке процессов, которая передается вашим grep для строки "processName".

Подстановка для «[p] rocessName» сама по себе будет соответствовать только «processName», но не строке «grep [p] rocessName».

0 голосов
/ 11 ноября 2009

вы не делаете тест. поставьте скобки вокруг условия теста следующим образом:

если [условие вашего тестирования]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...