Czy mogę zrobić coś podobnego do przekierowania standardowego procesu do pliku?
rustyx
@rustyx: Nietestowane, ale to powinno działać: utworzyć plik zamiast fajki, touch /tmp/thefile. Stdout to 1, więc call close (1); również użyć odpowiednich uprawnień do zapisu: call open ("/tmp/thefile", 0400). To echo…oczywiście nie jest potrzebne.
Ansgar Esztermann
To jest świetne! Używam tego do wysyłania odpowiedzi „y” lub „n” na niektóre procesy, które zostały całkowicie odłączone. Odłączony proces ma swoje standardowe wyjście w osobnym oknie. Kiedy jednak wykonuję tę sztuczkę, widzę, że nie „odbiera” „y” ani „n”, gdy tylko ją echo, muszę wyjść z gdb i odłączyć go, a następnie odpowiednio odbiera wszystkie echa, więc czy istnieje sposób na wykonanie tego bez konieczności wychodzenia z gdb, zanim proces odbierze dane wejściowe z fifo?
krb686
niestety po prostu wydaje się zawieszony call open("/tmp/fifo", 0600). każda pomoc byłaby bardzo mile
Spójrz na reptyr , który właśnie to robi. Strona github zawiera wszystkie informacje.
reptyr - Narzędzie do „ponownego pisania” programów.
reptyr to narzędzie do pobierania istniejącego programu i dołączania go do nowego terminala. Rozpoczął długotrwały proces nad ssh, ale musisz odejść i nie chcesz go przerywać? Po prostu uruchom ekran, użyj reptyr, aby go złapać, a następnie zabij sesję ssh i idź do domu.
STOSOWANIE
reptyr PID
„reptyr PID” pobierze proces o identyfikatorze PID i załączy go do bieżącego terminala.
Po dołączeniu proces pobierze dane wejściowe i zapisze dane wyjściowe w nowym terminalu, w tym ^ C i ^ Z. (Niestety, jeśli będziesz to robił w tle, nadal będziesz musiał uruchomić „bg” lub „fg” w starym terminalu. Prawdopodobnie nie jest to możliwe do naprawienia w rozsądny sposób bez łatania powłoki).
W standardach (POSIX, SUS) nie ma mowy, ale w wielu (większości?) Systemach jest to możliwe przy użyciu mechanizmów używanych przez debuggery. Zobacz odpowiedź Ansgara . Dzięki niemu rootmożesz nawet zrobić to z procesami innych użytkowników.
dmckee,
3
Wykonanie echo "test" > /dev/pts/1nie wyśle danych wejściowych do procesu 9947- wyświetli słowo „test” na terminalu tego procesu.
psmears,
6
EDYCJA : Jak powiedział Stephane Gimenez, nie jest to takie proste. Pozwala tylko na drukowanie na innym terminalu.
Możesz spróbować napisać do tego procesu za pomocą / proc . Powinien znajdować się w / proc / pid / fd / 0 , więc prosty:
echo "hello">/proc/PID/fd/0
powinien to zrobić. Nie próbowałem tego, ale powinno działać, o ile proces ten nadal ma prawidłowy deskryptor pliku stdin . Możesz to sprawdzić za pomocą ls -lon / proc / pid / fd / .
jeśli jest to link do / dev / null => jest zamknięty
jeśli jest to link do / dev / pts / X lub socket => jest otwarty
Zobacz nohup, aby uzyskać więcej informacji na temat utrzymania procesów w działaniu.
To nie takie proste. Na przykład, jeśli stdin jest połączone z terminalem, po echowłożeniu czegoś do urządzenia końcowego po prostu wydrukuje to, co napisałeś na terminalu, nie zostanie ono przesłane do procesu.
Stéphane Gimenez
5
Samo zakończenie wiersza poleceń &nie całkowicie odłączy proces, po prostu uruchomi go w tle. (Za pomocą zshmożesz &!go faktycznie odłączyć, w przeciwnym razie musisz to zrobić disownpóźniej).
Gdy proces działa w tle, nie będzie już odbierał danych wejściowych z terminala sterującego. Ale możesz wysłać go z powrotem na pierwszy plan, fga następnie ponownie odczytać dane wejściowe.
W przeciwnym razie nie jest możliwa zewnętrzna zmiana jego deskryptorów plików (w tym stdin) lub ponowne podłączenie zagubionego kontrolera… chyba że użyjesz narzędzi do debugowania (zobacz odpowiedź Ansgara lub spójrz na rettykomendę).
@Rogach stwierdził „Ten terminal jest już długo zamknięty”.
andcoz
1
@andcoz: Tak, ale miał szczęście, że program nie został PODSUMOWANY. Sugerowałem bezpieczniejszą metodę.
Stéphane Gimenez
tutaj, disown działa naprawdę tylko wtedy, gdy najpierw przekierowuję standardowe wyjście, jak w >>/dev/stderrprzeciwnym razie, kiedy zamknę terminal, proces „odrzucenia” też się skończy. Nigdy tak naprawdę tego nie zrozumiałem…
retty
,neercs
itp, a także zobaczyć serverfault.com/questions/24425 , serverfault.com/questions/115998Odpowiedzi:
Tak to jest. Po pierwsze, stworzenie rury:
mkfifo /tmp/fifo
. Użyj gdb, aby dołączyć do procesu:gdb -p PID
Następnie zamknij stdin:
call close (0)
; i otwórz go ponownie:call open ("/tmp/fifo", 0600)
Na koniec zapisz (z innego terminala, ponieważ gdb prawdopodobnie się zawiesi):
echo blah > /tmp/fifo
źródło
touch /tmp/thefile
. Stdout to 1, więccall close (1)
; również użyć odpowiednich uprawnień do zapisu:call open ("/tmp/thefile", 0400)
. Toecho…
oczywiście nie jest potrzebne.call open("/tmp/fifo", 0600)
. każda pomoc byłaby bardzo mileGdy oryginalny terminal nie jest już dostępny ...
reptyr
może być tym, czego chcesz, patrz https://serverfault.com/a/284795/187998Cytat stamtąd:
źródło
Jestem pewien, że nie możesz.
Sprawdź za pomocą
ps x
. Jeśli proces ma?
jak kontrolujący tty , nie można wysyłać dane wejściowe do niego więcej.W tym przykładzie możesz wysłać dane wejściowe do
9947
zrobienia czegoś takiegoecho "test" > /dev/pts/1
. Drugi proces (9942
) jest nieosiągalny.Następnym razem możesz użyć screen lub tmux, aby uniknąć tej sytuacji.
źródło
dtach
jeśli nie potrzebujesz całościscreen
.root
możesz nawet zrobić to z procesami innych użytkowników.echo "test" > /dev/pts/1
nie wyśle danych wejściowych do procesu9947
- wyświetli słowo „test” na terminalu tego procesu.EDYCJA : Jak powiedział Stephane Gimenez, nie jest to takie proste. Pozwala tylko na drukowanie na innym terminalu.
Możesz spróbować napisać do tego procesu za pomocą / proc . Powinien znajdować się w / proc / pid / fd / 0 , więc prosty:
powinien to zrobić. Nie próbowałem tego, ale powinno działać, o ile proces ten nadal ma prawidłowy deskryptor pliku stdin . Możesz to sprawdzić za pomocą
ls -l
on / proc / pid / fd / .Zobacz nohup, aby uzyskać więcej informacji na temat utrzymania procesów w działaniu.
źródło
echo
włożeniu czegoś do urządzenia końcowego po prostu wydrukuje to, co napisałeś na terminalu, nie zostanie ono przesłane do procesu.Samo zakończenie wiersza poleceń
&
nie całkowicie odłączy proces, po prostu uruchomi go w tle. (Za pomocązsh
możesz&!
go faktycznie odłączyć, w przeciwnym razie musisz to zrobićdisown
później).Gdy proces działa w tle, nie będzie już odbierał danych wejściowych z terminala sterującego. Ale możesz wysłać go z powrotem na pierwszy plan,
fg
a następnie ponownie odczytać dane wejściowe.W przeciwnym razie nie jest możliwa zewnętrzna zmiana jego deskryptorów plików (w tym stdin) lub ponowne podłączenie zagubionego kontrolera… chyba że użyjesz narzędzi do debugowania (zobacz odpowiedź Ansgara lub spójrz na
retty
komendę).źródło
>>/dev/stderr
przeciwnym razie, kiedy zamknę terminal, proces „odrzucenia” też się skończy. Nigdy tak naprawdę tego nie zrozumiałem…