Как я могу уничтожить и ожидать фоновых процессов для окончания в сценарии оболочки когда я Ctrl+C это?

Не ищите дистрибутив или поддистрибутив, ищите вместо этого инструменты для использования, чтобы сделать то, что Вы хотите сделать и затем проверить, можно ли выполнить все они в том компьютере. Необходимо детализировать то, что является "главными потребностями", на которых Вы сфокусируетесь. Например, если Вы хотите сфокусироваться на редактировании документа "пакета офисных программ" WYSIWYG, затем Рекомендуется попробовать что-то легче, чем LibreOffice (хотя, если Вы не открываете другое требующее много памяти приложение, я думаю, что Вам удастся выполнить libo).

Если Вы хотите просмотр веб-страниц, необходимо видеть, можно ли получить легкий браузер. Если Вы не полагаетесь слишком много на динамические ЧРЕЗМЕРНО УВЕЛИЧЕННЫЕ В РАЗМЕРЕ AJAX сайты и Вас действительно перемещение HTML, существуют некоторые варианты там, в пределах от dillo кому: lynx.

(Но Firefox должен смочь работать также — но если им не удалось избавиться от утечек, необходимо перезапустить его время от времени, также, несомненно, должны будете отключить любую усладу для глаз излишества и отключите сценарии и плагины, если они не будут действительно необходимы (NoScript, и Adblock и т.п. будет удобен здесь).)

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

Скорость ЦП не будет означать много, если Вы не соберетесь сделать интенсивное вычисление, компиляцию, обработку изображений, и т.д., или если Вы не выберете основанный на источнике дистрибутив (и, любопытно, узкое место с основанными на источнике дистрибутивами будет RAM, не ЦП).

Выбор дистрибутива бессмыслен, как только Вы выбираете инструменты, Вы хотите использовать. Конечно, если некоторый дистрибутив вынудит Вас пройти стандартную установку KDE под управлением Firefox с тысячей фоновых процессов для обеспечения "автоволшебного" поведения, то Вы испытаете некоторые затруднения при установке его.

Я предполагаю, что лучший выбор, безотносительно дистрибутива, который Вы выбираете, проверка, ли необходимо использовать некоторую специальную опцию выбрать пакеты и установить самую минималистскую систему, можно задумать, затем установить части, как Вы узнаете, Вам нужны они.

(Хорошая универсальная подсказка была бы: держитесь подальше от DES (Настольные среды) - менеджер окон достаточен для получения, ну, в общем, управления окнами. Но я предполагаю, можно ли избавиться от некоторых вещей, которые DES дает Вам, зависит от того, как Вы работаете и над Вашими вкусами.)

25
14.07.2015, 22:33
5 ответов

Ваш kill команда назад.

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

Если Вы пишете

kill -INT 0

это видит -INT как опция, и отправляет SIGINT кому: 0 (0 специальное число, означающее все процессы в группе текущего процесса).

Но если Вы пишете

kill 0 -INT

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

kill -TERM 0 -INT    

(это также попыталось бы отправить SIGTERM кому: -INT, который вызвал бы синтаксическую ошибку, но она отправляет SIGTERM кому: 0 во-первых, и никогда не получает это далеко.)

Таким образом, Ваш основной сценарий получает a SIGTERM прежде чем это доберется для выполнения wait и echo DONE.

Добавить

trap 'echo got SIGTERM' TERM

наверху, сразу после

trap 'killall' INT

и выполненный это снова для доказательства этого.

Как Stephane Chazelas указывает, Ваши второстепенные дети (process1, и т.д.), проигнорирует SIGINT по умолчанию.

В любом случае я думаю, отправляя SIGTERM имел бы больше смысла.

Наконец, я не уверен ли kill -process group как гарантируют, перейдет к детям сначала. Игнорирование сигналов, в то время как закрытие могло бы быть хорошей идеей.

Так попробуйте это:

#!/bin/bash
trap 'killall' INT

killall() {
    trap '' INT TERM     # ignore INT and TERM while shutting down
    echo "**** Shutting down... ****"     # added double quotes
    kill -TERM 0         # fixed order, send TERM not INT
    wait
    echo DONE
}

./process1 &
./process2 &
./process3 &

cat # wait forever
22
27.01.2020, 19:40
  • 1
    Спасибо, это работает! Это, кажется, было к проблеме. –  slipheed 16.11.2012, 19:43

К сожалению, команды, запущенные в фоне, установлены оболочкой проигнорировать SIGINT, и хуже, они не могут не проигнорировать его с trap. Иначе все, что необходимо было бы сделать,

(trap - INT; exec process1) &
(trap - INT; exec process2) &
trap '' INT
wait

Поскольку process1 и process2 получили бы SIGINT при нажатии Ctrl-C, так как они - часть той же группы процесса, которая является группой приоритетного процесса терминала.

Код выше будет работать с pdksh и zsh, которые в том отношении не являются совместимым POSIX.

С другими оболочками необходимо было бы использовать что-то еще для восстановления обработчика по умолчанию для SIGINT как:

perl -e '$SIG{INT}=DEFAULT; exec "process1"' &

или используйте другой сигнал как SIGTERM.

9
27.01.2020, 19:40

Если то, что Вы хотите, должно справиться с некоторыми фоновыми процессами, почему не использовать функции управления заданиями удара?

$ gedit &
[1] 2581
$ emacs &
[2] 2594
$ jobs
[1]-  Running                 gedit &
[2]+  Running                 emacs &
$ jobs -p
2581
2594
$ kill -2 `jobs -p`
$ jobs
[1]-  Interrupt               gedit
[2]+  Done                    emacs
1
27.01.2020, 19:40

Таким образом, я чинил вокруг с этим также. В Bash Вы можете определить функции и действительно представляете себе вещи с теми. Мои коллеги и я используем terminator, таким образом для пакетного выполнения мы обычно порождаем целый набор окон разделителя, если мы хотим просмотреть вывод (менее изящный, чем tmux вкладки, но можно использовать более подобное графическому интерфейсу ха-ха).

Вот установка, которую я придумал, а также пример материала, который можно выполнить:

#!/bin/bash
custom()
{
    terun 'something cool' 'yes'
    run 'xclock'
    terun 'echoes' 'echo Hello; echo Goodbye; read'
    func()
    {
        local i=0
        while :
        do
            echo "Iter $i"
            let i+=1
            sleep 0.25
        done
    }
    export -f func
    terun 'custom func' 'func'
}

# [ Setup ]
run()
{
    "$@" &
    # Give process some time to start up so windows are sequential
    sleep 0.05
}
terun()
{
    run terminator -T "$1" -e "$2"
}
finish()
{
    procs="$(jobs -p)"
    echo "Kill: $procs"
    # Ignore process that are already dead
    kill $procs 2> /dev/null
}
trap 'finish' 2

custom

echo 'Press <Ctrl+C> to kill...'
wait

Выполнение его

$ ./program_spawner.sh 
Press <Ctrl+C> to kill...
^CKill:  9835
9840
9844
9850
$ 

Отредактируйте @Maxim, просто видел Ваше предложение, которое делает его тонной более простой!Спасибо!

0
27.01.2020, 19:40

Для тех, кто просто хочет убить процесс и ждет он умирает, но не бесконечно :

Он ждет максимум 60 секунд на каждый тип сигнала.

Предупреждение: этот ответ никоим образом не связан с перехватом сигнала уничтожения и его отправкой.

# close_app_sub GREP_STATEMENT SIGNAL DURATION_SEC
# GREP_STATEMENT must not match itself!
close_app_sub() {
    APP_PID=$(ps -x | grep "$1" | grep -oP '^\s*\K[0-9]+' --color=never)
    if [ ! -z "$APP_PID" ]; then
        echo "App is open. Trying to close app (SIGNAL $2). Max $3sec."
        kill $2 "$APP_PID"
        WAIT_LOOP=0
        while ps -p "$APP_PID" > /dev/null 2>&1; do
            sleep 1
            WAIT_LOOP=$((WAIT_LOOP+1))
            if [ "$WAIT_LOOP" = "$3" ]; then
                break
            fi
        done
    fi
    APP_PID=$(ps -x | grep "$1" | grep -oP '^\s*\K[0-9]+' --color=never)
    if [ -z "$APP_PID" ]; then return 0; else return "$APP_PID"; fi
}

close_app() {
    close_app_sub "$1" "-HUP" "60"
    close_app_sub "$1" "-TERM" "60"
    close_app_sub "$1" "-SIGINT" "60"
    close_app_sub "$1" "-KILL" "60"
    return $?
}

close_app "[f]irefox"

Он выбирает приложение для уничтожения по имени или аргументам. Сохраните скобки для первой буквы имени приложения, чтобы избежать совпадения с самой grep.

С некоторыми изменениями вы можете напрямую использовать PID или более простой pidof имя_процесса вместо оператора ps .

Детали кода: Окончательная команда grep позволяет получить PID без конечных пробелов.

2
27.01.2020, 19:40

Теги

Похожие вопросы