Ок, разберём конкретно, по пунктам. 1. Команда ps предназначена для вывода информации в человекочитаемом виде, а не для парсинга. Поэтому разбирать её вывод — значит ходить по граблям. Если ну очень надо (хотя я таких случаев не встречал), абсолютно необходимо сразу отфильтровать строку заголовка, например tail -n +2. Также отсюда проистекают все последующие пункты. 2. Без какой бы то ни было необходимости используется опция ps "u". Это приводит к избыточному выводу, в частности, как следствие, из-за этого приходится давить лишнее костылём grep -v grep. 3. Регулярное выражение, содержащее имя команды, применяется ко всей строке вывода ps. Например, если грепнуть "cat", можно нагрепать все процессы пользователя pussycat и ещё какой-нибудь locate. Чтобы этого не происходило, надо делатьps -eo comm | tail -n +2 | grep '^cat$' | wc -l 4. У выше приведённой команды тоже есть недосаток: ps в качестве соответствующей процессу команды выводит урезанный argv[0]. Если вместо спецификатора формата comm использовать command, то ps выведет все елементы argv[], так что надо будет дорабатывать регулярку. Но эту уже становится слшком сложно, потому что всплывают новые нюансы (например в argv[0] может быть абсолютный или относительный путь, в том числе содержащий пробельные и даже непечатаемые символы). Лучше таки использоватьpgrep -ax cat 5. Многие забывают, что содержимое argv[0] может вообще не иметь никакого отношения к реально запущенному бинарю. Если нужно точное соответствие имени бинаря, то в случае GNU coreutils надо использоватьps -eo ucmd а POSIX ps, как и pgrep, вообще не годится. А если хочется соответствие не только имени, но и полного пути, забудь про ps вообще и бери в руки find:find /proc/*/exe -lname /bin/cat (это linux only).
|