Napisałem prosty skrypt, który jest echo
jego PID:
#/bin/bash
while true; do
echo $$;
sleep 0.5;
done
Korzystam ze wspomnianego skryptu (mówi 3844
wielokrotnie) w jednym terminalu i próbuję znaleźć tail
deskryptor pliku w innym:
$ tail -f /proc/3844/fd/1
Nie drukuje niczego na ekranie i zawiesza się do ^c
. Dlaczego?
Ponadto wszystkie deskryptory plików STD (IN / OUT / ERR) łączą się z tymi samymi punktami:
$ 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
Czy to normalne?
Uruchamianie Ubuntu GNOME 14.04.
Jeśli uważasz, że to pytanie należy do SO lub SU zamiast UL, powiedz.
linux
bash
proc
file-descriptors
cprn
źródło
źródło
Odpowiedzi:
Zrób
strace
ztail -f
, to wszystko wyjaśnia. Interesująca część:Co to robi? Ustawia
inotify
moduł obsługi pliku, a następnie czeka, aż coś się stanie z tym plikiem. Jeśli jądro mówitail
przez ten moduł obsługi inotify, że plik zmienił się (normalnie został dołączony), totail
1) szuka 2) odczytuje zmiany 3) zapisuje je na ekranie./proc/3844/fd/1
w twoim systemie jest dowiązanie symboliczne/dev/pts/14
, które jest urządzeniem znakowym. Nie ma czegoś takiego jak „mapa pamięci”, do której można uzyskać dostęp. Tak więc nie ma nic, którego zmiany mogłyby zostać podpisane w inotify, ponieważ nie ma obszaru dysku ani pamięci, do którego można by uzyskać dostęp.To urządzenie postaci jest wirtualnym terminalem, który praktycznie działa tak, jakby był gniazdem sieciowym. Programy działające na tym wirtualnym terminalu łączą się z tym urządzeniem (tak jakbyś telnet-ted do portu tcp) i zapisywał, w co chcą pisać. Są też rzeczy bardziej złożone, na przykład blokowanie ekranu, sekwencje kontrolne terminali i takie są zwykle obsługiwane przez
ioctl()
połączenia.Myślę, że chcesz jakoś obejrzeć wirtualny terminal. Można to zrobić na Linuksie, ale nie jest to takie proste, wymaga trochę funkcji sieciowych proxy i nieco trudnego użycia tych
ioctl()
wywołań. Ale istnieją narzędzia, które mogą to zrobić.Obecnie nie pamiętam, który pakiet debian ma narzędzie do tego celu, ale przy odrobinie googlingu można to łatwo znaleźć.
Rozszerzenie: jak wspomniano tutaj @Jajesh (daj mu +1, jeśli mi dałeś), nazwa narzędzia
watch
.Rozszerzenie nr 2: wspomniane @kelnos,
cat /dev/pts/14
wystarczyło również proste . Próbowałem tego i tak, zadziałało, ale nie poprawnie. Nie eksperymentowałem z tym dużo, ale wydaje mi się, że dane wyjściowe przesyłane do tego wirtualnego terminala trafiły albo docat
polecenia, albo do jego pierwotnej lokalizacji, i nigdy do obu. Ale nie jest to pewne.źródło
tail
jest poprawna (bit obserwacyjny inotify), ale jest niepoprawny, ponieważ tak naprawdę bardzo łatwo jest robić to, co chcesz: po prostu użyjcat
zamiasttail
.cat
też dla mnie nie działa, wisi tak samo jak ogon i wszystko, co mogę zrobić, toctrl+c
.echo $$
na,echo $$ >> foo
więc teraz jest plik i proces otwiera go i dołącza do niego co 0,5 sekundy. Nadal nie mogę uzyskać do niego dostępu za pomocą deskryptora pliku, a wszystkie deskryptory plików w/proc/$pid/fd/
(ale 254, które prowadzą dotest.sh
samego skryptu), prowadzą do/dev/pts/14
. W jaki sposób bash ma dostępfoo
do zapisu?Pliki w
/dev/pts
nie są zwykłymi plikami, są uchwytami dla wirtualnych terminali.pts
Zachowanie do czytania i pisania nie jest symetryczna (to jest, co jest napisane w nie może być później odczytywane z niej, jak zwykły plik lub FIFO / rury), ale za pośrednictwem procesu, który utworzył dany terminal wirtualny: niektóre spotykane są xterm lub ssh lub agetty lub screen. Proces kontrolny zwykle wysyła naciśnięcia klawiszy do procesów, które odczytująpts
plik i wyświetlają na ekranie to, co zapisują napts
.W ten sposób
tail -f /dev/pts/14
zostanie wydrukowany klawiszy dotknięciu na terminalu, z którego rozpoczął swój scenariusz, a jeśli nie wiadomość pojawi się w terminalu.echo meh > /dev/pts/14
meh
źródło
tail -f /dev/pts/14
nie drukuje kluczy, których dotykam na tym terminalu. To jednak interesująca odpowiedź. Dzięki.Jakiś czas temu znalazłem trochę obejść że czasami odpowiada na konieczność sprawdzenia, co jest wyprowadzany do STDOUT, zakładając, że masz
pid
procesu i można urodziła oczy nieprzyjazne wyniki:źródło
Wydaje mi się, że w tym celu, a nie z ogonkiem, trzeba będzie obserwować wynik.
Mam nadzieję, że tego właśnie potrzebujesz.
źródło
watch
. To, co próbuję zrobić, to zerknąć na wynik już uruchomionego procesu, więcwatch
to nie pomaga.