Каков самый простой способ "отсоединить/демонзировать" Bash script?

То, что я пытаюсь сделать, это написать Bash script, который спит в течение установленного промежутка времени, прежде чем использовать команду mac say, чтобы произнести какой-то текст.

Я хотел бы иметь возможность запустить команду, а затем закрыть терминал, чтобы он все еще говорил в установленное время. Я просмотрел nohup, отделил, запустил и поставил процесс в фоновом режиме, но все эти решения по-прежнему приводят к завершению процесса после закрытия терминала. Должен ли я каким-то образом сделать какой-то процесс детского зомби, чтобы это сделать? Какое лучшее решение? Спасибо вам

# Simple Example of main code
sleep 10;
say hello;
exit;

Ответы

Ответ 1

В разделе 3.7.6 руководства Bash указано:

Оболочка завершает работу по умолчанию при получении SIGHUP. Перед выходом из интерактивной оболочки перенаправляет SIGHUP на все задания, работает или останавливается. Остановленные задания отправляются SIGCONT в убедитесь, что они получают SIGHUP. Чтобы предотвратить отправку оболочки SIGHUP на конкретную работу, ее следует удалить из таблицы рабочих мест с отключенным встроенным (см. Раздел 7.2 [Встроенные функции управления заданиями], стр. 88) или отмечен, чтобы не получать SIGHUP с помощью disown -h.

Таким образом, использование nohup или disown должно сделать трюк. Или вы можете сделать:

trap "" 1
sleep 10
say hello

В строке 'trap' игнорируется сигнал 1, SIGHUP; вы также можете написать 'trap "" HUP ".

Ответ 2

nohup yourscript.sh 10 "hello" &

#     ^your script  ^^your parameter 1
#                      ^^^^^^^your parameter 2

Отсоедините script от терминала, и он не будет убит, когда терминал закроется. Обратите внимание на & в конце; вы можете передавать параметры в свой script как обычно. Тогда yourscript.sh может быть:

#!/bin/bash

sleep $1;
say "$2";
exit;

Ответ 3

Вам нужно использовать nohup и background вместе. Я просто попробовал это на OS-X, чтобы убедиться, что он работает:

nohup ./say-hello.sh &

Ответ 4

Если вы не запустите его с помощью nohup, как уже было предложено, вам нужно будет использовать disown как таковой...

$ ./say-hello.sh &
[1] 12345
$ disown -h %1

Вам нужно будет указать номер задания (вторая строка в приведенном выше примере, номер задания находится в скобках, а другой - идентификатор процесса), чтобы вы могли передать его в disown.

Ответ 5

Ваш script может выглядеть так:

#!/bin/bash
read -p "Text: " text
read -p "Delay: " delay
nohup bash -c "sleep $delay; say \"$text\" &"

Затем вы обычно запускаете script:

$ your_script
Text: hello
Delay: 10

и внешний script завершит работу, но Sleep&Say™ останется в фоновом режиме.

Ответ 6

Используйте nohup yourscript.sh &, как предполагал Писквор.

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

Убийство вашей программы может быть невозможно без kill -9, и это может быть немного жестоким. Если вы этого не хотите, я предлагаю объединять файл, например end.txt каждую минуту или около того. Если ваша программа обнаруживает наличие такого файла в рабочем каталоге, он должен выйти изящно.

Ответ 7

В зависимости от вашего определения "легко" ответ может быть daemon.

Ответ 8

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

Используя screen, вы можете легко запустить script, закройте сеанс терминала /ssh, а затем вернитесь назад и снова присоединитесь к script. Сделайте это довольно легко.

Установка

Сначала установите screen:

sudo apt-get install screen

Detach

а затем введите bash файл

#!/usr/bin/env bash
screen -S myscreen -d -m bash -c 'ls; exec bash'

(замените ls на вашу программу) Он создаст (-S) "экран" с именем myscreen и отделит его (-d), запустив команды внутри `` -c``` вариант. Затем, если вы хотите позже подключиться к этому экрану:

И добавьте позже

screen -rd myscreen

если вы хотите перечислить весь текущий экран:

screen -ls

Примечание: если вы хотите закрыть экран, когда закончите, удалите bash в конце команды.