Dołącz do wyjścia procesu w celu wyświetlenia

112

W jaki sposób „dołączyłbym” widok konsoli / terminala do danych wyjściowych aplikacji, aby zobaczyć, co on mówi?

Jak odłączyć się od danych wyjściowych aplikacji bez jej zabijania?

Zwykle, jeśli uruchomisz rozmowną aplikację za pomocą wiersza poleceń, zobaczysz wszelkiego rodzaju wspaniałe wyniki. Załóżmy jednak, że mam szczególnie rozmowne programowanie, takie jak KINO, i chcę zobaczyć jego wyjście w dowolnym momencie bez ponownego uruchamiania go z wiersza poleceń. Nie mogę; przynajmniej nie wiem jak.

aggitan
źródło
1
Czy masz w swoim procesie symbol debugowania? Czy działa w środowisku produkcyjnym? A jeśli tak, czy chcesz, aby NIGDY nie był wstrzymywany?
yves Baumes
Kiedy mam napady problemów ze stabilnością z programami użytkownika końcowego, takimi jak kino (zawiesza się i zabija mój dźwięk), chcę wiedzieć, jak / dlaczego się zawiesił, aby móc go naprawić. To nie jest program, który rozwijam, ale technika, którą chciałbym poznać, aby rozwiązywać problemy. Spróbuję poniżej sugestii.
aggitan

Odpowiedzi:

18

Jest tu kilka opcji. Jednym z nich jest przekierowanie danych wyjściowych polecenia do pliku, a następnie użycie „tail”, aby wyświetlić nowe wiersze, które są dodawane do tego pliku w czasie rzeczywistym.

Inną opcją jest uruchomienie programu w „ekranie”, który jest rodzajem tekstowej aplikacji terminala. Sesje ekranowe można dołączać i odłączać, ale nominalnie są przeznaczone tylko do użytku przez tego samego użytkownika, więc jeśli chcesz je udostępniać między użytkownikami, jest to duży ból w dupie.

Don Werve
źródło
1
„Jest tutaj kilka opcji. Jedną z nich jest przekierowanie wyjścia polecenia do pliku, a następnie użycie 'tail', aby wyświetlić nowe linie, które są dodawane do tego pliku w czasie rzeczywistym”. Czy można to zrobić z już uruchomionymi aplikacjami?
aggitan
2
Prawdopodobnie będziesz potrzebować tail -f $ log_file, aby uzyskać dane wyjściowe zapisane w pliku. Nie, nie ma sposobu, aby to zrobić z już uruchomioną aplikacją.
Varkhan
@aggitan: Nie. W przypadku istniejących aplikacji będziesz musiał je zrestartować, ponieważ już powiązały swoje wejścia / wyjścia z terminalem sterującym.
Don Werve
289

Myślę, że mam tutaj prostsze rozwiązanie. Po prostu poszukaj katalogu, którego nazwa odpowiada PID, którego szukasz, w pseudosystemie plików dostępnym pod /procścieżką. Więc jeśli masz uruchomiony program, którego ID to 1199, cdto:

$ cd /proc/1199

Następnie poszukaj fdkatalogu poniżej

$ cd fd

Ten fdkatalog zawiera obiekty deskryptorów plików, których używa twój program (0: stdin, 1: stdout, 2: stderr) i tylko tail -ften, którego potrzebujesz - w tym przypadku stdout):

$ tail -f 1
licorna
źródło
9
Nie mogłem użyć, tailponieważ w moim przypadku dane wyjściowe zostały przekierowane do innego procesu w celu wprowadzenia danych, ale morepokazały mi aktualne dane.
Ωmega
10
Jeden z najbardziej przykuwających uwagę postów na tej stronie!
robert
2
morepracuje dla mnie. ubuntu 14.04 w procesie węzłowym
Shih-Min Lee
1
To nie działa dla mnie z procesem Java, który wywołuje System.out.println. W ogóle nie ma wyjścia do / proc / [pid] / fd / 1
Nick
1
Próbowałem utworzyć reprodukcję używając poniższego, ale bezskutecznie: `` docker run -it --name container1 ubuntu bash -c -i 'COUNT = 0; while true; do echo Utrzymaj rytm parkietu; (( LICZBA ++)); uśpienie 1; echo \ "Liczba to: \ $ {LICZBA} \"; gotowe; " `` W innym terminalu: `` docker exec -it container1 tail -f / proc / 1 / fd / 1 ''
JacobWuzHere
54

Szukałem dokładnie tego samego i stwierdziłem, że możesz:

strace -ewrite -p $PID

Nie jest to dokładnie to, czego potrzebujesz, ale jest dość blisko.

Próbowałem przekierować dane wyjściowe, ale to nie zadziałało. Może dlatego, że proces zapisywał do gniazda, nie wiem.

Paul Scheltema
źródło
dzięki działa, ale dane wyjściowe są obcięte, np. dla ping: write (1, "64 bajty z 1.0.0.1: icmp_seq =" ..., 56) = 56
izy
8

W jaki sposób „dołączyłbym” widok konsoli / terminala do danych wyjściowych aplikacji, aby zobaczyć, co on mówi?

Jeśli chodzi o to pytanie, wiem, że można przechwycić dane wyjściowe, nawet jeśli nie uruchomiłeś polecenia sceen przed uruchomieniem procesu.

Chociaż nigdy tego nie próbowałem, znalazłem interesujący artykuł, który wyjaśnia, jak korzystać z GDB (i bez ponownego uruchamiania procesu).

przekierowanie-wyjście-z-działającego-procesu

Gruntownie:

  1. Sprawdź listę otwartych plików dla swojego procesu, dzięki / proc / xxx / fd
  2. Dołącz swój proces do GDB
  3. Gdy jest wstrzymany, zamknij interesujący Cię plik, wywołując funkcję close () (możesz dowolną funkcję swojego procesu w GDB. Podejrzewam, że potrzebujesz symboli debugowania w swoim procesie ..)
  4. Otwórz nowy plik, wywołując funkcję create () lub open (). (Spójrz na komentarze na końcu, zobaczysz, że ludzie sugerują użycie dup2 (), aby upewnić się, że ten sam uchwyt będzie używany)
  5. Odłącz proces i pozwól mu działać.

Nawiasem mówiąc, jeśli używasz systemu operacyjnego Linux na pudełku i386, komentarze mówią o lepszym narzędziu do przekierowania wyjścia na nową konsolę: „retty” . Jeśli tak, rozważ jego użycie.

yves Baumes
źródło
6

U mnie to zadziałało:

  1. Zaloguj się jako właściciel procesu (nawet rootodmowa pozwolenia)

    ~$ su - process_owner
    
  2. Dostosuj deskryptor pliku, jak wspomniano w wielu innych odpowiedziach.

    ~$ tail -f /proc/<process-id>/fd/1 # (0: stdin, 1: stdout, 2: stderr)
    
akki
źródło
2

Chciałem zdalnie obserwować proces aktualizacji yum, który był uruchamiany lokalnie, więc chociaż prawdopodobnie istniały bardziej wydajne sposoby na zrobienie tego, oto co zrobiłem:

watch cat /dev/vcsa1

Oczywiście chciałbyś użyć vcsa2, vcsa3 itp., W zależności od używanego terminala.

Tak długo, jak moje okno terminala miało taką samą szerokość jak terminal, na którym było uruchamiane polecenie, mogłem zobaczyć migawkę ich aktualnego wyjścia co dwie sekundy. Inne polecenia zalecane w innym miejscu nie działały szczególnie dobrze w mojej sytuacji, ale to wystarczyło.

RedScourge
źródło