Я написал простой скрипт, который echo
-es его PID:
#/bin/bash
while true; do
echo $$;
sleep 0.5;
done
Я запускаю указанный скрипт (он говорит 3844
снова и снова) в одном терминале и пытаюсь tail
использовать дескриптор файла в другом:
$ tail -f /proc/3844/fd/1
Он ничего не выводит на экран и пока не зависает ^c
. Почему?
Кроме того, все дескрипторы файлов STD (IN / OUT / ERR) ссылаются на одни и те же точки:
$ ls -l /proc/3844/fd/
total 0
lrwx------ 1 mg mg 64 sie 29 13:42 0 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 1 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 2 -> /dev/pts/14
lr-x------ 1 mg mg 64 sie 29 13:42 254 -> /home/user/test.sh
lrwx------ 1 mg mg 64 sie 29 13:42 255 -> /dev/pts/14
Это нормально?
Запуск Ubuntu GNOME 14.04.
Если вы думаете, что этот вопрос относится к SO или SU вместо UL, скажите.
Ответы:
Сделать
strace
изtail -f
, это все объясняет. Интересная часть:Что оно делает? Он устанавливает
inotify
обработчик для файла, а затем ждет, пока что-то произойдет с этим файлом. Если ядро сообщаетtail
через этот обработчик inotify, что файл изменился (обычно был добавлен), тоtail
1) ищет 2) читает изменения 3) записывает их на экран./proc/3844/fd/1
В вашей системе есть символическая ссылка/dev/pts/14
, которая является символьным устройством. Не существует такой вещи, как «карта памяти», к которой можно получить доступ. Таким образом, нет ничего, чьи изменения могли бы быть подписаны в inotify, потому что нет диска или области памяти, к которой можно было бы получить доступ.Это символьное устройство представляет собой виртуальный терминал, который практически работает как сетевой сокет. Программы, запущенные на этом виртуальном терминале, подключаются к этому устройству (как если бы вы подключились по tcp-порту) и записывали то, что они хотят записать. Также есть более сложные вещи, например, блокировка экрана, последовательности управления терминалом и т. Д., Которые обычно обрабатываются
ioctl()
вызовами.Я думаю, вы хотите как-то посмотреть виртуальный терминал. Это может быть сделано в Linux, но это не так просто, для этого требуются некоторые функции, подобные сетевому прокси, и немного хитрое использование этих
ioctl()
вызовов. Но есть инструменты, которые могут это сделать.В настоящее время я не могу вспомнить, в каком пакете Debian есть инструмент для этой цели, но, немного погуглив, вы можете легко найти это.
Расширение: как @Jajesh упомянул здесь (дайте ему +1, если вы дали мне), инструмент назван
watch
.Расширение №2: упомянутое @kelnos, простого
cat /dev/pts/14
было тоже достаточно. Я пробовал это, и да, это работало, но не правильно. Я не много экспериментировал с этим, но мне кажется, что выход, поступающий в этот виртуальный терминал, поступает либо вcat
команду, либо в исходное местоположение, а не в оба. Но это не точно.источник
tail
это правильно (бит наблюдения inotify), но он неверен в том, что на самом деле очень просто делать то, что вы хотите: просто используйтеcat
вместоtail
.cat
у меня тоже не работает, зависает так же, как хвост, и все, что я могу сделать, это делатьctrl+c
.echo $$
наecho $$ >> foo
так, что теперь есть файл, и процесс открывает его и добавляет к нему каждые 0,5 секунды. Я до сих пор не могу получить к нему доступ через файловый дескриптор, и все файловые дескрипторы в/proc/$pid/fd/
(но 254, который ссылается наtest.sh
сам скрипт) ссылаются на/dev/pts/14
. Как bash accessfoo
пишет в него?Файлы в
/dev/pts
не являются обычными файлами, они являются ручками для виртуальных терминалов.pts
Поведение для чтения и письма не является симметричным (то есть, что написано там позже можно прочитать из него, как обычный файл или ФИФО / трубы), но опосредовано процессом , который создал виртуальный терминал: некоторые распространенные из них xterm или ssh или agetty или экран. Процесс управления обычно отправляет нажатия клавиш процессам, которые читаютpts
файл, и отображают на экране то, что они пишут наpts
.Таким образом,
tail -f /dev/pts/14
будет печатать ключи вы нажмете на терминал , с которого вы начали свой сценарий, и если вы сообщение появится в терминале.echo meh > /dev/pts/14
meh
источник
tail -f /dev/pts/14
не печатать ключи, которые я нажимаю на этом терминале. Это интересный ответ, хотя. Спасибо.Некоторое время назад я нашел своего рода обходной путь, который иногда отвечает на необходимость проверить, что выводится в STDOUT, при условии, что у вас есть
pid
процесс, и вы можете обнажить недружелюбные результаты:источник
Я предполагаю, что для этого, вместо того, чтобы следить, что вам нужно было бы наблюдать за результатами.
Надеюсь, это то, что вам нужно.
источник
watch
. То, что я пытаюсь сделать, это просмотреть результаты уже запущенного процесса, так чтоwatch
это не помогает.