Подавить уведомление об убийстве разветвленной команды - PullRequest
2 голосов
/ 03 апреля 2009

Предположим, у меня есть скрипт bash (foo.sh), который в очень упрощенном виде выглядит следующим образом:

echo "hello"
sleep 100 &
ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
echo "bye"

Третья строка имитирует pkill, которого у меня нет по умолчанию в Mac OS X, но вы можете думать о нем так же, как pkill. Однако когда я запускаю этот скрипт, я получаю следующий вывод:

hello
foo: line 4: 54851 Killed                  sleep 100
bye

Как мне подавить линию посередине, чтобы все, что я вижу, было hello и bye?

Ответы [ 6 ]

14 голосов
/ 03 апреля 2009

В то время как disown может иметь побочный эффект глушения сообщения; это то, как вы запускаете процесс таким образом, что сообщение действительно отключается, не отказываясь от контроля над процессом.

{ command & } 2>/dev/null

Если вам все еще нужен собственный stderr команды (просто отключение сообщения оболочки на stderr), вам нужно отправить stderr процесса реальному stderr:

{ command 2>&3 & } 3>&2 2>/dev/null

Чтобы узнать, как работает перенаправление:

И, кстати; не использовать kill -9.

Я также чувствую себя обязанным прокомментировать ваше:

ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9

Это поймает взгляд любого пользователя UNIX / Linux с подсказкой. Более того, каждый раз, когда вы разбираете ps, фея умирает. Сделайте это:

kill $!

Даже такие инструменты, как pgrep, по сути, сломаны. Хотя они лучше справляются с процессами сопоставления, фундаментальные недостатки все еще присутствуют:

  • Гонка. К тому времени, когда вы получаете вывод PID, анализируете его и используете его для чего-то другого, PID, возможно, уже исчез или даже был заменен совершенно не связанным процессом.
  • Ответственность: В модели процесса UNIX родитель должен управлять своим потомком, и никто другой не должен. Родитель должен сохранить PID своего ребенка, если он хочет иметь возможность сигнализировать об этом, и только родитель может надежно сделать это. Ядра UNIX были разработаны с учетом того, что пользовательские программы будут придерживаться этого шаблона, а не нарушать его.
3 голосов
/ 03 апреля 2009

Как насчет отречения? В основном это работает для меня на Bash на Linux.

echo "hello"
sleep 100 &
disown
ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
echo "bye"

Редактировать: Соответствует коду плаката лучше.

1 голос
/ 18 апреля 2012

Существует гораздо лучшее решение, использующее «wait» здесь: https://stackoverflow.com/a/10200191/1208218

1 голос
/ 03 апреля 2009

Сообщение реально. Код также убил процесс grep.

Запустите ps ax | grep sleep, и вы должны увидеть свой процесс grep в списке.

В этом случае я обычно делаю ps ax | grep sleep | grep -v grep

РЕДАКТИРОВАТЬ: Это ответ на старую форму вопроса, где автор исключил исключение grep для последовательности уничтожения. Я надеюсь, что я все еще получу немного ответа за первый тайм.

0 голосов
/ 11 марта 2013

Еще один способ отключить сообщения о завершении задания - поместить вашу команду в основу sh -c 'cmd &'.

И как уже указывалось, подражать pkill не нужно; вместо этого вы можете сохранить значение $! в другой переменной.

echo "hello"
sleep_pid=`sh -c 'sleep 30 & echo ${!}' | head -1`
#sleep_pid=`sh -c '(exec 1>&-; exec sleep 30) & echo ${!}'`
echo kill $sleep_pid
kill $sleep_pid
echo "bye"
0 голосов
/ 03 апреля 2009

Вы пытались деактивировать контроль работы? Это неинтерактивная оболочка, поэтому я думаю, по умолчанию она отключена, но попробовать не мешает ... Она регулируется переменной оболочки -m (monitor).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...