Как перенаправить stdout, stderr обратно в/dev/tty
Я просто ssh-ed на какой-то удаленный сервер и обнаружил, что stdout
и stderr
всех команд/процессов, которые я пытаюсь запустить в bash, перенаправляется куда-то.
Итак, у меня возникли следующие вопросы.
Как определить:
1) Какой файл stdout
, stderr
перенаправлен в Linux?
и
2) И как перенаправить по умолчанию stdout
и stderr
обратно в /dev/tty?
Спасибо заранее.
Ответы
Ответ 1
Команда, которая должна делать буквально то, что вы просили в (2),
exec >/dev/tty 2>&1
Но я подозреваю, что ваш анализ проблемы неверен. Было бы полезно увидеть вывод ssh -v ...
(где ...
- это любые аргументы, введенные в исходной команде ssh
).
Ответ 2
Команда:
ls -l /proc/$$/fd/{1,2}
покажет вам, какие файлы открыты как stdout (дескриптор файла 1) и stderr (дескриптор файла 2).
Ответ 3
Это можно сделать, только если ваша тоскающая оболочка запускается с помощью команды pipe to tee
с другой консолью в качестве параметра.
Позвольте мне объяснить.
Если вы входите в систему /dev/tty1
, а кто-то еще входит в систему /dev/tty2
. Если вы запустите свою оболочку (bash), выполнив следующую команду, все STDOUT/STDERR будут перенаправлены/скопированы в другую оболочку (/dev/tty2
в этом случае).
bash 2>&1 | tee /dev/tty2
Итак, кто-то, сидящий в /dev/tty2
, увидит всю вашу деятельность.
Если кто-то войдет в систему с оболочкой, это /bin/bash 2>&1 | tee /dev/tty2
вместо /bin/bash
Это произойдет каждый раз, когда он войдет в систему. Но я не уверен, что в этом случае можно установить оболочку для входа.
Если кто-то перенаправляет все выходные данные вашей оболочки таким образом, вы можете проверить это, просто проверив, работает ли какой-либо tee
в фоновом режиме.
ps ax | grep tee
Это выведет что-то вроде
tee /dev/tty2
Ответ 4
Ответ на ваш первый вопрос можно найти в /proc/self/fd
. Он содержит символические ссылки на файлы (или другие вещи, трубы, сокеты и т.д.), К которым подключен ваш экземпляр bash.
[email protected]:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 May 21 02:18 0 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 1 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
lr-x------ 1 root root 64 May 21 02:18 3 -> /proc/15529/fd/
[email protected]:~# ls -l /proc/self/fd < /dev/null
total 0
lr-x------ 1 root root 64 May 21 02:18 0 -> /dev/null
lrwx------ 1 root root 64 May 21 02:18 1 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
lr-x------ 1 root root 64 May 21 02:18 3 -> /proc/15536/fd/
[email protected]:~# ls -l /proc/self/fd | cat
total 0
lrwx------ 1 root root 64 May 21 02:18 0 -> /dev/pts/3
l-wx------ 1 root root 64 May 21 02:18 1 -> pipe:[497711]
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
lr-x------ 1 root root 64 May 21 02:18 3 -> /proc/15537/fd/
[email protected]:~#
В первом примере вы можете увидеть первые 3 дескриптора файла (которые являются стандартным выводом, вводом и ошибкой, соответственно) все указывают на мой псевдотерминал /dev/pts/3
. Во втором примере я перенаправил вход в /dev/null
, поэтому стандартный дескриптор входного файла указывает на /dev/null
. И в последнем примере я отправил вывод ls
в cat
через канал, и стандартный дескриптор входного файла отражает это. Насколько я знаю, нет способа найти, какой процесс имеет другой конец трубы. Во всех примерах есть четвертый файловый дескриптор, который представляет дескриптор, который ls
имеет для чтения /proc/self/fd
. В этом случае он говорит /proc/15537
, потому что /proc/self
на самом деле является символической ссылкой на /proc/pid
, где pid
является PID процесса, обращающегося к /proc/self
.