Проверьте количество запущенных скриптов с помощью ps

Я пишу скрипт (show_volume.sh), который может вызываться несколько раз через короткие промежутки времени. Мне нужен способ определить, существует ли более одного запущенного экземпляра этого скрипта. Я подумал, что могу использовать ps, поэтому написал эту функцию на Bash:

is_only_process(){
    PCOUNT=`ps -a | grep show_volume.sh | wc -l`
    echo $PCOUNT
    if (( PCOUNT==1 )); then
        return 1 
    fi  
    return 0
}

Поэтому я добавил эти 2 строки

is_only_process
sleep 4

и запускал этот скрипт один раз, но вывод echo $PCOUNT для меня не имеет никакого смысла. Я всегда получаю значение 2, а не 1, как ожидалось. Когда я запускаю эту команду

ps -a | grep show_volume.sh | wc -l

с другого терминала во время работы скрипта я получаю значение 1. Это почти то же самое, когда я запускаю этот скрипт несколько раз подряд, например. 10 раз, используя цикл for. Сценарий сам определяет слишком высокие значения, в то время как я получаю правильные значения при использовании другого терминала.

Теперь, почему этот сценарий определяет эти нечетные значения?


person helios35    schedule 17.12.2010    source источник


Ответы (4)


В данный момент ps работает процесс grep show_volume.sh, так что вы всегда считаете grep!

Простое решение, grep s[h]ow_volume.sh. grep (не оболочка) свернет [h] в h и будет искать то, что вы хотите, но ваш grep не будет соответствовать самому себе, потому что он будет иметь [] в параметре.

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

person Nathan Kidd    schedule 17.12.2010
comment
В данный момент ps запускается процесс grep show_volume.sh, так же запущен - технически не корректно. бывают случаи, когда ps завершится до того, как сработает grep, и в этом случае grep не будет засчитано. поэтому вы должны удовлетворить оба случая. - person moinudin; 17.12.2010
comment
По какой-то причине это не решает мою проблему. Я попытался заменить выражение на pgrep show_volume.sh | wc -l или ps -a | grep s[h]ow_volume.sh | wc -l, но скрипт ведет себя точно так же, как и раньше. - person helios35; 17.12.2010
comment
@marcog, причина, по которой я дал, - это правильное техническое объяснение того, почему в grep появлялись 2 процесса. Однако вы правы в том, что, как правило, вы должны знать, что вы можете не получить такое поведение в зависимости от характеристик производительности вашей системы. - person Nathan Kidd; 17.12.2010
comment
@ helios35, я предлагаю вам изучить простой вывод ps -a | grep s[h]ow_volume.sh и работать с ним. (Лично я бы использовал ps -ef | ..., чтобы убедиться, что вы поймаете случай, когда скрипт передается в качестве параметра в оболочку) - person Nathan Kidd; 17.12.2010
comment
ps -ef | grep s[h]ow_volume.sh гелиос 25929 1 0 15:22 ? 00:00:00 /bin/bash /home/helios/scripts/show_volume.sh helios 25961 25929 0 15:22 ? 00:00:00 /bin/bash /home/helios/scripts/show_volume.sh это вывод, когда я запускаю скрипт один раз. Я понятия не имею, почему есть 2 процесса, которые на самом деле не отличаются. - person helios35; 18.12.2010
comment
Второй экземпляр был запущен первым (PID показывает, что он дочерний). Внимательно проверьте свой сценарий на наличие рекурсивного вызова. - person Nathan Kidd; 22.12.2010

Если вы запускаете скрипт от имени разных пользователей, то ps -a будет показывать экземпляры только для текущего пользователя и только для тех, у кого подключен терминал. Используйте ps -ax или ps -e.

pgrep -c

покажет количество без использования wc.

person Dennis Williamson    schedule 18.12.2010

Попробуйте также исключить grep, так как сам ваш grep также содержит show_volume.sh, например

ps -a | grep show_volume.sh | grep -v grep | wc -l
person ajreal    schedule 17.12.2010
comment
Спасибо, но это не меняет поведение скрипта. Та же ошибка все еще возникает. - person helios35; 17.12.2010

Решение предоставлено ajreal:

пс-а | grep show_volume.sh | grep -v grep | туалет -л

должно сработать. Если это не так, пожалуйста, предоставьте вывод

пс-а | grep show_volume.sh | грэп -в грэп

здесь

person Ilya Dyakov    schedule 08.03.2011
comment
вывод: ps -e | grep show_volume.sh | grep -v grep 15956 ? 00:00:00 show_volume.sh 15971 ? 00:00:00 show_volume.sh два процесса, хотя я выполнил скрипт только один раз и исключил grep. - person helios35; 12.03.2011
comment
grep -v grep — это антипаттерн. Как этого избежать — древний FAQ. - person tripleee; 11.05.2016