2010-02-26 5 views
2

сценарий оболочки Unix с единственной целью - подсчитать количество запущенных процессов qmail (может быть что-то еще). Легкая вещь, но должна быть какая-то ошибка в коде:linux shell scripting kiddie's question

#!/bin/bash 
rows=`ps aux | grep qmail | wc -l` 
echo $rows 

Поскольку

echo $rows 

всегда показывает большее количество строк (11), чем если бы я просто подсчета строк в

ps aux | grep qmail 

Всего 8 строк. Так ли это работает и в вашей системе?

+0

@roe, не думайте об этом, «grep qmail» уже удалил строку заголовка PID/PPID. – paxdiablo

+0

Это должно быть отфильтровано grep. – ConcernedOfTunbridgeWells

+0

@paxdiablo: Конечно ... глупо меня. – falstro

ответ

1

Нет, так как я не бегу qmail. Тем не менее, вы хотите, на минимум, исключает процесс запуска вашего Grep:

ps aux | grep qmail | grep -v grep 

Для отладки, вы можете сделать:

rows=`ps aux | grep qmail` 
echo $rows >debug.input 
od -xcb debug.input 

(чтобы увидеть свой вклад в сценарий в большой подробно), а затем переписать сценарий временно как:

#!/bin/bash 
rows=`cat debug.input | wc -l` 
echo $rows 

Таким образом, вы можете увидеть вход и выяснить, какой эффект он оказывает на ваш код, даже когда вы его отлаживаете.

Хороший отладчик в конечном итоге научится изменять только одну переменную за раз. Если вы меняете свой код, чтобы заставить его работать, это переменная - не позволяйте также вводить изменения в код.

+0

Почему «grep qmail» должен печатать строки, содержащие «grep»? –

+0

+1 за хороший момент, хотя он должен был появиться и в его ручном запуске. – falstro

+3

потому что есть дополнительный процесс, называемый 'grep qmail', который содержит ...' qmail'. – LiraNuna

0

Использование

$ /sbin/pidof qmail

+0

это ничего не показывает (qmail запущен), и я не знаю, почему – peterson

+0

Он должен работать. Попробуйте указать полный путь к qmail. Может быть, запустить как root? –

3

В настоящее время с Linux, есть pgrep. Если у вас есть в вашей системе, вы можете пропустить grep -v grep

$ var=$(pgrep bash) # or `pgrep bash | wc -l` 
$ echo $var 
2110 2127 2144 2161 2178 2195 2212 2229 
$ set -- $var; echo ${#} 
8 

также, если ваша команда ps имеет -C вариант, другой способ

$ ps -C bash -o pid= | wc -l 

, если нет, то вы можете установить класс символов в вашем Grep модель

$ ps aux|grep [q]mail | wc -l 
0

несколько способов ...

ps -e | grep ' [q]mail' | wc -l 
ps -C qmail -opid= | wc -l 
pidof qmail | tr ' ' '\n' | wc -l 
2

Похоже, что вы считаете, что процесс grep сам и строка заголовка обычно печатаются до его вывода.

Я хотел бы предложить что-то более, как:

qprocs = $ (п.с. auxwww | Grep -c "[д] почта")

... обратите внимание, что GNU grep имеет "-c" чтобы напечатать «счет» совпадений, а не сами строки.Трюк с регулярным выражением здесь должен соответствовать qmail без соответствия строковой строке, которая находится в командной строке grep. Таким образом, мы берем любой символ в строке и обертываем его в квадратные скобки таким образом, чтобы это был один класс «класс». Регулярное выражение: [q] mail соответствует строке qmail без соответствия строке [q] mail.

Обратите внимание, что даже с этим регулярным выражением вы все равно можете найти ложные положительные совпадения. Если вы действительно хотите быть более точным, вы должны предоставить строку пользовательского выходного формата в свою команду ps (см. Страницы руководства) или вы должны подать ее через pipemill, или вы должны проанализировать вывод команды ps на основе полей (используя awk или cut или петля while read). (Опция -o до ps на сегодняшний день является самой легкой среди них).

0

pgrep находится во многих дистрибутивах Linux, и я представляю себе доступным для других Unices.

[[email protected] ~]$ whatis pgrep 
pgrep    (1) - look up or signal processes based on name and other attributes 
[[email protected] ~]$ pgrep mingetty 
1920 
1921 
1922 
1923 
1924 

В вашем случае, pgrep qmail | wc -l следует сделать трюк.