Как отсоединить управляющий терминал от командной строки?

255
Omnifarious

Я знаю о, nohupи это не будет делать то, что я хочу:

Пример:

$ nohup sleep 600 2>/dev/null >/dev/null </dev/null& [1] 21844 $ ps -ef | fgrep -e 'sleep > TTY' UID PID PPID C STIME TTY TIME CMD me 21844 19313 0 09:37 pts/9 00:00:00 sleep 600 

Как видите, сон по-прежнему pts/9является управляющим терминалом. Я не хочу, чтобы у него был какой-либо управляющий терминал. Частично потому, что программа, которую я хочу использовать (это не так, sleepесли вы не догадались), пытается открыть управляющий терминал, чтобы задать мне вопросы, и я хочу посмотреть, как он себя ведет, если не может. Как мне это сделать?

1

3 ответа на вопрос

1
Jim L.

Это решение FreeBSD, но, возможно, аналогичная методика подойдет для вашей ОС.

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

#!/bin/sh [ -f /tmp/my-semaphore-file ] || { touch /tmp/my-semaphore-file my_command_stack > /dev/null 2>&1 } 

Возможно, он не предназначен для производственного использования, но если вы просто хотите проверить, как работает ваш стек команд без управляющего терминала, он это сделает. Оболочка не позволит cron запустить команду снова, пока вы:

rm /tmp/my-semaphore-file 

at(1) также является опцией и является «почти» решением командной строки:

echo 'my_command_stack > /dev/null 2>&1' | at now+1 minute 
Даже «сейчас» работает. Это лучше, чем мое "Вы не можете сделать это". ответ. Omnifarious 5 лет назад 0
0
zymhan

Вы также должны использовать, disownчтобы отделить процесс от tty.

https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Попробуйте запустить nohup sleep 600 2>/dev/null >/dev/null </dev/null& disownи посмотреть, даст ли это желаемый результат.

Нет, у сна все еще есть что-то в столбце `TTY '. Я проверил это, хотя и не ожидал, что «отречение» будет иметь эффект. Отбрасывание управляющего терминала - это то, что должно быть сделано, когда процесс запускается AFAIK. Omnifarious 5 лет назад 0
Ах, да, глядя на этот пост, кажется, что «Отречение» не исправит это: https://superuser.com/questions/1196406/linux-view-and-kill-disowned-process zymhan 5 лет назад 0
Эта небольшая командная строка приводит к процессу `python3` без управляющего терминала:` sh -c 'nohup python3 -c "import os, time; time.sleep (5); os.setsid (); time.sleep (600 ) "& '/ dev / null 2> / dev / null &` Omnifarious 5 лет назад 0
0
Omnifarious

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

Выполнение этого в Unix / POSIX / Linux в целом возможно, но требует очень специфической последовательности системных вызовов, включающей несколько процессов. И объяснение того, почему и как потребуется объяснение вещей на уровне кода, что я не считаю подходящим для суперпользователя.

И хотя раньше были инструменты командной строки, которые делали бы это (я думаю, что это daemonizeбыл один из них), они, похоже, уже не получили широкого распространения. По крайней мере, Fedora их не упаковывает. Одна из причин, вероятно, заключается в том, что это имеет интересные последствия с точки зрения таких вещей, как systemdпредставление о сеансе пользователя совершенно отдельно от групп процессов и идентификаторов сеансов, на которые обычно опирается традиционное ориентированное на терминал управление заданиями.

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