Squeak.ru - шаблоны программирования

Несоответствие между perl grep и cli grep

Я делаю следующее:

#!/usr/bin/perl  
use strict;  
use warnings;  

my $proc = `ps -ef|grep -c myscriptname`;  
print $proc;  

Это печатает 2, когда я запускаю его внутри скрипта.

ps -ef|grep -c myscriptname в командной строке просто показывает: 1
Почему?

то же самое для my $proc = qx/ps -ef|grep -c myscriptname/

ОБНОВЛЕНИЕ
Чтобы было ясно, я запускаю этот фрагмент из somerandomscript.pl

Обновление 2
Следуя совету edorqui, я удаляю -c, получая:

12013 15777 15776 0 14:11 pts/6 00:00:00 sh -c ps -ef | grep myscriptname   
12013 15779 15777 0 14:11 pts/6 00:00:00 grep myscriptname Argument "12013 15777 15776 0 14:11 pts/6 00:00:00 sh -c ps..." isn't numeric in numeric gt (>) at somerandomscript.pl line 8  

изнутри скрипта

09.08.2013

  • Вы отображали хиты? Будет ли одним из них сам grep? 09.08.2013
  • Это довольно плохой способ определить, что у вас запущен процесс, особенно когда возможно запустить более одного экземпляра процесса (или сценария). 09.08.2013
  • @devnull: Как лучше? 09.08.2013
  • Один из способов — заставить скрипт записать PID в файл и удалить его, когда скрипт завершится (возможно, в конце самого скрипта). Теперь всякий раз, когда вам нужно проверить, работает ли скрипт, вместо этого опрашивайте файл. 09.08.2013

Ответы:


1

Команда ps -ef показывает сам grep.

Чтобы пропустить это поведение, попробуйте найти условие регулярного выражения, которое не соответствует самому grep:

ps -ef | grep myscript[n]ame

или что-то подобное может сделать это:

ps -ef | grep myscriptnam[e]

Объяснение

Если вы запускаете команду sleep в фоновом режиме:

$ sleep 100 &
[1] 9768

а затем найдите его с помощью ps -ef:

$ ps -ef | grep sleep
me    9768  3673  0 14:00 pts/6    00:00:00 sleep 100
me    9771  3673  0 14:00 pts/6    00:00:00 grep --color=auto sleep

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

$ ps -ef | grep -v grep | grep sleep

или используйте регулярное выражение в коде, чтобы процесс grep не совпадал:

$ ps -ef | grep slee[p]
me    9768  3673  0 14:00 pts/6    00:00:00 sleep 100

потому что линия

me    9771  3673  0 14:00 pts/6    00:00:00 grep --color=auto sleep

не совпадает в grep slee[p].

См. объяснение в соответствующем разделе.

09.08.2013
  • Я не уверен, что вы имеете в виду под myscript[n]ame. Также я проверяю из другого скрипта. Пожалуйста, смотрите обновление в ОП. 09.08.2013
  • Но я запускаю скрипт из другого скрипта. Дело не в том, что я получаю 2, потому что мой скрипт + grep. Я проверяю другое имя скрипта. 09.08.2013
  • Что, если вы просто grep myscriptname (без -c) и распечатаете результаты? Какой из них отсутствует? 09.08.2013
  • Когда я запускаю это, я получаю от скрипта: 12013 15777 15776 0 14:11 pts/6 00:00:00 sh -c ps -ef | grep myscriptname 12013 15779 15777 0 14:11 pts/6 00:00:00 grep myscriptname Argument "12013 15777 15776 0 14:11 pts/6 00:00:00 sh -c ps..." isn't numeric in numeric gt (>) at somerandomscript.pl line 8. 09.08.2013
  • Из cli я получаю: 12013 16965 15732 0 14:13 pts/6 00:00:00 grep myscriptname 09.08.2013
  • @Cratylus Мммм, не стесняйтесь обновить мой ответ этим выводом, чтобы я мог его правильно увидеть. Комментарии действительно плохи для проверки строк кода! 09.08.2013
  • Обновлен ОП для вашего удобства 09.08.2013
  • @Cratylus, теперь я вижу. 2-я строка показывает, что есть проблема при вызове команды grep -c. 09.08.2013
  • @fedorqui, нет, вторая строка является артефактом Perl-скрипта, который Cratylus фактически использует, смешивая предупреждение Perl STDERR с выводом. Когда Кратил удалил -c из своего вызова grep, он изменил содержимое $proc. Чего он не показал нам, так это того, что он делает что-то вроде if ($proc > 0) ... в сценарии, а perl теперь жалуется, что $proc не числовое. 09.08.2013
  • @fedorqui, иначе говоря, ваша первоначальная интерпретация совершенно верна. :) Из CLI ps Cratylus обычно завершается до того, как grep даже войдет в таблицу процессов. 09.08.2013
  • @pilcrow вы очень хорошо отслеживаете ошибки :) молодец, теперь это имеет смысл. Спасибо! 09.08.2013
  • @Cratylus, вы можете проверить комментарии pilcrow, которые он только что написал? Интересно проследить, что происходило раньше и что происходит сейчас при использовании grep без -c. 09.08.2013
  • @pilcrow: Да, ты прав! Я проверял if($proc > 0). 10.08.2013
  • @fedorqui: посмотри мой комментарий к pilcrow 10.08.2013

  • 2

    Я предполагаю, что ваш perl-скрипт называется "myscriptname".

    Когда вы запускаете этот сценарий, у вас появляется новый процесс (perl myscriptname.pl), и он отображается командой ps -ef. Другой связан с командой grep (у него есть текст, который вы ищете)

    09.08.2013

    3

    ответ @fedorqui правильный - grep соответствует своему собственному вызову в таблице процессов и, возможно, вызову его родителя shell тоже, хотя проблемы со временем означают, что это не всегда происходит из CLI.

    Однако другим подходом, избегающим grep в пользу perl, будет:

    my $count = () = qx(ps -e -o cmd) =~ /myscriptname/mg;
    # Now $count tells you the number of times myscriptname appears in the process table
    

    См. этот ответ, чтобы понять, почему пустые скобки используются выше. Также обратите внимание, что вам не нужен полный вывод ps (-f), вы просто хотите сопоставить имя команды (-o cmd).

    09.08.2013
  • +1. Но я не совсем согласен с вашим объяснением. Теперь я думаю, что счетчик равен 2, потому что он считает сам grep и порожденную оболочку, имеющую grep в качестве аргумента. 10.08.2013
  • @Cratylus, да, хорошее разъяснение; Я обновлю, чтобы отразить это. 10.08.2013

  • 4

    Взгляните на pgrep и pkill. Это стандартные команды Linux, их намного проще использовать, чем пытаться выполнить ps, а затем grep.

    Кроме того, если вы используете ps, взгляните на параметры -o. Они позволяют отображать нужные столбцы и дают возможность удалить заголовок.

    09.08.2013
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...