bash: тихо убить фоновую функцию процесса - PullRequest
53 голосов
/ 19 апреля 2011

shell gurus,

У меня есть скрипт оболочки bash, в котором я запускаю фоновую функцию, скажем foo(), для отображения индикатора выполнения для скучной и длинной команды:

foo()
{
    while [ 1 ]
    do
        #massively cool progress bar display code
        sleep 1
    done
}

foo &
foo_pid=$!

boring_and_long_command
kill $foo_pid >/dev/null 2>&1
sleep 10

Теперь, когда foo умирает, я вижу следующий текст:

/home/user/script: line XXX: 30290 Killed                  foo

Это полностью разрушает удивительность моего, в остальном, невероятно крутого дисплея индикатора выполнения.

Как сделатьЯ избавляюсь от этого сообщения?

Ответы [ 9 ]

57 голосов
/ 20 апреля 2011
kill $foo_pid
wait $foo_pid 2>/dev/null

Кстати, я не знаю о вашем чрезвычайно крутом индикаторе прогресса, но вы видели Pipe Viewer (pv)?http://www.ivarch.com/programs/pv.shtml

27 голосов
/ 14 мая 2014

Просто столкнулся с этим сам и понял, что "отречение" - это то, что мы ищем.

foo &
foo_pid=$!
disown

boring_and_long_command
kill $foo_pid
sleep 10

Сообщение о смерти печатается, потому что процесс все еще находится в списке оболочек отслеживаемых "заданий". Команда disown удалит самый последний порожденный процесс из этого списка, так что при его завершении не будет сгенерировано отладочное сообщение, даже если SIGKILL (-9).

5 голосов
/ 19 апреля 2011

Попробуйте заменить вашу строку kill $foo_pid >/dev/null 2>&1 на строку:

(kill $foo_pid 2>&1) >/dev/null

Обновление

Этот ответ неверен по причине, объясненной @ mklement0 в его комментарии:

Причина, по которой этот ответ неэффективен для фоновых заданий, заключается в том, что Bash сам асинхронно, после того, как команда kill завершена, выводит сообщение о состоянии убитой работы, которое вы не можете подавить напрямую - если вы не используете wait, как в принятом ответе.

4 голосов
/ 17 ноября 2011

Это решение, которое я нашел для аналогичной проблемы (хотел отобразить метку времени при длительных процессах).Это реализует функцию killsub, которая позволяет вам тихо убить любую подоболочку, пока вы знаете pid.Обратите внимание, что в инструкции прерывания важно включить: в случае, если сценарий прерывается, подоболочка не будет продолжать работать.

foo()
{
    while [ 1 ]
    do
        #massively cool progress bar display code
        sleep 1
    done
}

#Kills the sub process quietly
function killsub() 
{

    kill -9 ${1} 2>/dev/null
    wait ${1} 2>/dev/null

}

foo &
foo_pid=$!

#Add a trap incase of unexpected interruptions
trap 'killsub ${foo_pid}; exit' INT TERM EXIT

boring_and_long_command

#Kill foo after finished
killsub ${foo_pid}

#Reset trap
trap - INT TERM EXIT
3 голосов
/ 19 апреля 2011

Этот "хак", кажется, работает:

# Some trickery to hide killed message
exec 3>&2          # 3 is now a copy of 2
exec 2> /dev/null  # 2 now points to /dev/null
kill $foo_pid >/dev/null 2>&1
sleep 1            # sleep to wait for process to die
exec 2>&3          # restore stderr to saved
exec 3>&-          # close saved version

, и он был вдохновлен здесь .Мировой порядок восстановлен.

1 голос
/ 20 апреля 2011

Добавить в начале функции:

trap 'exit 0' TERM
0 голосов
/ 26 октября 2018

Вы можете использовать set +m, прежде чем подавить это.Подробнее об этом здесь

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

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

#!/bin/bash

foo()
{
   while [ 1 ]
   do
       sleep 1
   done
}

#foo &
#foo_pid=$!

export -f foo
foo_pid=`sh -c 'foo & echo ${!}' | head -1`

# if shell does not support exporting functions (export -f foo)
#arg1='foo() { while [ 1 ]; do sleep 1; done; }'
#foo_pid=`sh -c 'eval "$1"; foo & echo ${!}' _ "$arg1" | head -1`


sleep 3
echo kill ${foo_pid}
kill ${foo_pid}
sleep 3
exit
0 голосов
/ 23 января 2013

Еще один способ сделать это:

    func_terminate_service(){

      [[ "$(pidof ${1})" ]] && killall ${1}
      sleep 2
      [[ "$(pidof ${1})" ]] && kill -9 "$(pidof ${1})" 

    }

позвонить с помощью

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