Как вывести работающий фоновый процесс на передний план? - PullRequest
0 голосов
/ 04 июля 2019

У меня запущен процесс на сервере, по какой-то причине моя клиентская система была перезапущена, поэтому я снова подключаюсь к серверу, используя терминал.

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

Есть ли способ, чтобы я мог вывести STDOUT моего запущенного процесса на текущий терминал?

Спасибо.

1 Ответ

0 голосов
/ 04 июля 2019

См. Этот ответ .

Сначала я запускаю команду cat > foo1 в одном сеансе и проверяю, что данные из stdin копируются в файл. Затем в другой сессии я перенаправляю вывод.

Сначала найдите PID процесса:

$ ps aux | grep cat
rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat

Теперь проверьте дескрипторы файлов, которые у него открыты:

$ ls -l /proc/6760/fd
total 3
lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1
lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5

Теперь запустите GDB:

$ gdb -p 6760 /bin/cat
GNU gdb 6.4.90-debian

[license stuff snipped]

Attaching to program: /bin/cat, process 6760

[snip other stuff that's not interesting now]

(gdb) p close(1)
$1 = 0
(gdb) p creat("/tmp/foo3", 0600)
$2 = 1
(gdb) q
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: /bin/cat, process 6760

Команда p в GDB напечатает значение выражения, выражение может быть функцией для вызова, это может быть системный вызов ... Поэтому я выполняю системный вызов close() и передаю дескриптор файла 1, затем Я выполняю системный вызов creat(), чтобы открыть новый файл. Результат creat() был 1, что означает, что он заменил предыдущий дескриптор файла. Если бы я хотел использовать один и тот же файл для stdout и stderr или если бы я хотел заменить дескриптор файла каким-то другим номером, то мне нужно было бы вызвать системный вызов dup2() для достижения этого результата.

Для этого примера я решил использовать creat() вместо open(), потому что здесь меньше параметров. Макросы C для флагов не могут использоваться из GDB (он не использует заголовки C), поэтому я должен был бы прочитать файлы заголовков, чтобы обнаружить это - это не так сложно сделать, но это займет больше времени. Обратите внимание, что 0600 является восьмеричным разрешением для владельца, имеющего права на чтение / запись, и для группы и других, не имеющих доступа. Также будет полезно использовать 0 для этого параметра и позже запустить chmod для файла.

После этого я проверяю результат:

ls -l /proc/6760/fd/
total 3
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/foo3 <====
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5

Ввод дополнительных данных в cat приводит к добавлению файла /tmp/foo3.

Если вы хотите закрыть исходный сеанс, вам нужно закрыть все файловые дескрипторы для него, открыть новое устройство, которое может быть управляющим tty, а затем вызвать setsid().

...