grep терпит неудачу в сценарии выскочки

2102
Thorsten Schöning

У меня есть выскочка конфигурации для службы, которая должна проверять наличие процесса при его запуске. Это звучит довольно просто, но я уже 3 часа пытаюсь решить эту проблему, и я заблудился. Кажется, проблема в том, что некоторые операторы grep приводят к выходу скрипта из upstart, что приводит к сбою при запуске сервиса. Но выскочка ничего не регистрирует, она просто выходит из сценария и исчезает.

Ниже приведены несколько примеров строк, которые вызывают проблему: первое эхо и выходные данные его grep регистрируются, второе эхо регистрируется, но не выводятся его grep. После второго выскочка эха просто выходит из скрипта и останавливается. Проблема заключается в добавлении опции -v или чего-то другого, например, использования классов регулярных выражений, таких как [[: digit:]]. Кажется, мне нужно убежать от некоторых персонажей, но я просто не знаю как. Простое -v или что-то подобное не работает.

script echo grep ps ax | grep "postgres: wal writer process" | grep "grep" echo grep2 ps ax | grep "postgres: wal writer process" | grep -v "grep" end script 

У кого-нибудь есть представление о том, что я делаю неправильно и как решить проблему?

4

1 ответ на вопрос

5
tripleee

As explained in the manual, all scripts run with sh -e. That means any unhandled command failure will terminate the script with an error. If you have code which might return failure, you would code it like

command || true 

or wrap it in a conditional or something.

By the by, your code is better written as

ps ax | grep "[p]ostgres: wal writer process" 

See also https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep

So in summary, you would probably be looking for something like

if ps aux | grep '[p]ostgres: wal writer process' then : already running else : start it up fi 

Now that grep is run as part of a conditional, a failure is no longer considered unhandled (even if you don't have an else clause!) and so it will run safely under set -e.

Ваше утверждение также не работает, но теперь я думаю, что понимаю причину: утверждение должно потерпеть неудачу, если оно не находит подходящих строк, что является полностью допустимым случаем. После операторов grep у меня есть if, который проверяет код ошибки последнего оператора, но из-за кода ошибки 1, если строка преобразования не найдена, и "sh -e", если if никогда не достигается. Там нет ничего плохого с escape-символами или что-то еще. 10 лет назад 0
Вы должны исправить `grep foo bar; если [$? = 0]; затем ... `к более простому, более устойчивому и более идиоматическому` if grep foo bar; тогда ... ` tripleee 10 лет назад 1
Я не мог получить что-то вроде `if [ps ax | grep "postgres: Wal Writer Process" | grep -v "grep"] `или` if [ps ax | grep "[p] ostgres: процесс записи в wal"] `даже без [] формируют if и экранируют | или [р] на работу. 10 лет назад 0
Может быть, смотрите также http://stackoverflow.com/questions/10586213/encounter-unary-operator-expected-in-bash-script/10586252#10586252 tripleee 10 лет назад 0
Или, остроумно, `если ps aux | grep "[p] ostgres: Wal Writer Process"; затем ... `и обратите внимание, в частности, на отсутствие квадратных скобок вокруг команд. tripleee 10 лет назад 1
Вы правы, проблема была []. Я пробовал без них раньше, но, возможно, это не сработало, потому что моя конфигурация выгрузки использует символическую ссылку и не обновлялась после моих изменений. Теперь это работает. Большое спасибо! 10 лет назад 0