Nohup не действует, когда закрыть терминал и завершить процесс, работающий в фоновом режиме? - PullRequest
7 голосов
/ 20 июня 2020

nohup command & может продолжать выполнение команды после закрытия терминала. Я хочу воспроизвести все mp3-файлы c в каталоге Music.

ls Music/*mp3 |xargs -d "\n" mplayer  

ls Music/*mp3 может перечислить все mp3-файлы в каталоге Music, отправить его через канал с xargs, -d "\n" - для обработки пробелов в именах файлов.

Я хочу перенаправить все stdout и stderr в /dev/null и запустить его в фоновом режиме.

ls Music/*mp3 |xargs -d "\n" mplayer > /dev/null 2>&1 &

Это отлично работает, но я хочу, чтобы он работал после закрытия терминала.

nohup ls Music/*mp3 | xargs -d "\n" mplayer > /dev/null 2>&1 &
ls Music/*mp3 | xargs -d "\n" nohup mplayer > /dev/null 2>&1 &
ls Music/*mp3 | nohup xargs -d "\n" mplayer > /dev/null 2>&1 &

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

disown может решить проблему, но я хотел бы решить проблему с использованием nohup.

ls Music/*mp3 | xargs -d "\n" mplayer > /dev/null 2>&1 & disown

Ответы [ 4 ]

9 голосов
/ 23 июня 2020

nohup command означает «запустить command и игнорировать сигналы HUP ».

Поэтому, прежде чем мы сможем эффективно использовать nohup, мы должны спросить: когда и как отправляется SIGHUP? Как сказано в руководстве Bash: «Перед выходом интерактивная оболочка повторно отправляет SIGHUP всем заданиям, запущенным или остановленным». . Далее говорится, что правильный способ подавить это поведение - использовать disown. Я понимаю, что вы спрашиваете о nohup, но стоит отметить, что disown - это предполагаемый и более простой способ достичь sh того, чего вы хотите. Обратите внимание, что disown - это , а не эквивалент nohup.

Причина, по которой nohup сложно работать здесь, заключается в том, что он применяется к одному процессу, тогда как & создает фон задание всей команды конвейер , который может состоять из нескольких процессов. Это означает, что вам нужно nohup каждую команду в конвейере, чтобы гарантировать, что отдельные команды не получают SIGHUP, например:

$ nohup ls Music/*mp3 2>/dev/null | nohup xargs -d "\n" nohup mplayer &> /dev/null &

Это должно работать, хотя Я не тестировал его с этими c командами. Если это не так, скорее всего, другой процесс, который вы не запускаете напрямую, все еще получает сигнал SIGHUP. С этим труднее справиться, именно поэтому у нас есть disown.

предложение manishg также разумно; переместив конвейер в отдельный процесс, вы можете nohup этот процесс, который, в свою очередь, должен предотвратить получение SIGHUP своих дочерних процессов при закрытии оболочки.

Все сказанное, вам не нужны здесь ls и xargs; find может использоваться с аналогичным эффектом и упростит рассуждение о команде. Попробуйте:

$ nohup find Music -maxdepth 1 -name '*mp3' -exec mplayer {} + &> /dev/null &
4 голосов
/ 23 июня 2020

Я хочу воспроизвести все mp3-файлы c в каталоге Musi c.

Обычно ls или xargs для этого не нужны. Вы можете упростить весь конвейер до mplayer Music/*mp3 ✱. Это не только безопаснее для специальных имен файлов, но также решает вашу проблему с nohup:

nohup mplayer Music/*mp3 &> /dev/null &
✱ Существует только один случай, когда эта команда не работает и `ls * | xargs` успешно. Если у вас очень большое количество файлов mp3, вы можете столкнуться с ограничением длины командной строки. Предел в байтах задается `getconf ARG_MAX`. В моей системе это 2097152, что означает, что вам потребуется как минимум 8000 файлов, если максимальная длина имени файла составляет 255 байтов. С более короткими именами файлов у вас может быть еще больше файлов. Например, если ваши mp3-файлы обычно имеют длину около 40 байт, вы можете использовать более 44000 файлов.
0 голосов
/ 23 июня 2020

Есть два способа закрыть терминал. exit способ:

Введите exit в терминал и щелкните enter.

cross способ: Щелкните cross в правом верхнем углу.

Чтобы проиллюстрировать их тем же файлом png. введите описание изображения здесь nohup может вступить в силу только с exit способом для всех следующих команд (проверено всех не менее трех раз в терминале).

ls Music/*mp3 |xargs -d "\n" nohup mplayer  > /dev/null 2>&1 &
ls  Music/*mp3 | nohup  xargs  -d  "\n"  mplayer  > /dev/null  2>&1  &
nohup ls Music/*mp3 2>/dev/null | nohup xargs -d "\n" nohup mplayer &> /dev/null &
nohup find Music -maxdepth 1 -exec mplayer {} \; &> /dev/null &
nohup mplayer Music/*mp3 &> /dev/null &

Небольшая ошибка для nohup sh -c и nohup bash -c:

nohup sh -c 'ls  Music/*mp3 |  xargs  -d  "\n"  mplayer' &
[1] 4581
nohup: ignoring input and appending output to 'nohup.out'
nohup bash -c 'ls  Music/*mp3 |  xargs  -d  "\n"  mplayer' &
[1] 16831
nohup: ignoring input and appending output to 'nohup.out'

Когда закрыть терминал с помощью cross way, musi c не будет воспроизводиться в фоновом режиме для всех вышеперечисленных команд.

Команда, оканчивающаяся на disown, будет go, чтобы воспроизвести музыку c в фоновом режиме любым способом (exit или cross). Лучше выполнить команду exe c disown, чтобы go включал воспроизведение музыки c в фоновом режиме после закрытия терминала.

0 голосов
/ 23 июня 2020

nohup так не работает с трубами. используйте следующий способ:

nohup sh -c 'ls  Music/*mp3 |  xargs  -d  "\n"  mplayer' &
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...