Zapisywanie na standardowe tło procesu

25

Używam Ubuntu 10.04 i uruchomiłem serwer w tle (mój serwer i) przez ssh. Działa dobrze, ale potrzebuję sposobu, aby uzyskać standardowe wejście serwera, ponieważ jedynym sposobem kontrolowania serwera jest ta metoda.

Czy jest jakiś sposób, aby dostać się do standardu już działającego procesu, abym mógł do niego napisać (i mam nadzieję, że przeczytam jego standard)? Oczywiście, gdybym miał to teraz robić, zacznę od przekierowania FIFO na standardowe wejście, ale niestety jest już na to trochę za późno.

Jakieś pomysły?

tajmorton
źródło
Czy nie możesz po prostu przenieść go z powrotem na pierwszy plan? ('jobs' wyświetli aktualny proces w tle, 'fg $ X' przeniesie zadanie z powrotem na pierwszy plan, ctrl + b wstrzyma zadanie i powróci do powłoki, podczas gdy 'bg' będzie kontynuował zatrzymany proces w tło)
symcbean

Odpowiedzi:

10

Możesz spróbować napisać do katalogu / proc pid. Powiedz, że pid demonów wynosi 2000, spróbuj napisać do / proc / 2000 / fd / 0

katriel
źródło
Dzięki ... Znalazłem to zaraz po tym, jak to opublikowałem (po dniu patrzenia - typowym). To wydaje się działać (o ile faktycznie wysyła dane do programu). Niestety program nie akceptuje poleceń. Przetestowałem go na serwerze lokalnym i na pewno widzę, że dane się pojawiają, ale program nie rozpoznaje poleceń. Muszę ręcznie nacisnąć klawisz Enter na terminalu serwera, a następnie mówi tylko nierozpoznane polecenie. Może jakiś dziwny java?
Utknąłem
1
co powiesz na echo -e "coś \ n"> / proc / 2000 / fd / 0?
katriel
W rzeczywistości nie jest to zawsze szukanie, ponieważ / proc / <pid> / fd / 0 wskazuje na / dev / pts <jakąś liczbę> przynajmniej w niektórych systemach ...
bk138,
Pierwsza odpowiedź na serverfault.com/questions/178457/… zauważa, że ​​to podejście w rzeczywistości nie działa.
barrycarter
2
To nie działa. Powłoka normalnie (gdy nie są używane żadne potoki ani przekierowania) uruchamia polecenie z deskryptorami plików 0poprzez 2ustawienie na ten sam plik, którym zwykle jest terminal wirtualny (coś w rodzaju /dev/pty/...). Polecenie następnie odczytuje z FD 0i zapisuje do FD 1i 2komunikuje się z terminalem wirtualnym (np. Przez SSH lub bezpośrednio z emulatorem terminala). Jeśli jakikolwiek inny proces uzyskuje dostęp do tego pliku (np. Poprzez /proc), dzieje się dokładnie to samo, tzn. Zapis do niego zapisuje w terminalu, a nie w poleceniu.
Feuermurmel,
29

Możesz uruchomić serwer z nazwanym potokiem (fifo) jako wejściem:

mkfifo /tmp/srv-input
cat > /tmp/srv-input &
echo $! > /tmp/srv-input-cat-pid
cat /tmp/srv-input | myserver &

cat > /tmp/srv-input &Jest ważne, aby uniknąć serwer otrzymać EOF. Co najmniej jeden proces musi mieć otwarte fifo na piśmie, aby Twój serwer nie otrzymał EOF. PID tego polecenia jest zapisywany w /tmp/srv-input-cat-pidpliku dla późniejszego zabicia.

W przypadku, gdy już uruchomiłeś serwer, musisz użyć debuggera, takiego jak gdbdołączenie do procesu, aby przekierować go stdindo fifo:

gdb -p PID
call close(0)
call open(0, "/tmp/srv-input", 0600)

A następnie zrób coś takiego, jak poniżej, aby wysłać dane wejściowe na serwer (w razie potrzeby w innym oknie terminala):

echo "command" > /tmp/srv-input

Aby wysłać EOF na serwer, musisz zabić cat > /tmp/srv-inputproces, w którym zapisano PID /tmp/srv-input-cat-pid file.

W przypadku GDB wystarczy wyjść z GDB, a EOF zostanie wysłany.

jfg956
źródło
1
jest to o wiele bardziej przenośne podejście niż podejście @katriel, ponieważ / proc / 2000 / fd / 0 nie jest standardem we wszystkich systemach.
Wcześniej99
Sztuczka z „cat> / tmp / srv-input &” uratowała mi pewne bóle głowy. Dziękuję Ci!
Wcześniej99
Co mkfifo /tmp/srv-input; tail -f /tmp/srv-input | myserver &? Dzięki temu rura będzie również otwarta ...
bk138,
@ bk138: wydaje mi się, że ogon powinien działać, ale jest tylko jeden sposób, aby się upewnić: test.
jfg956
tailnie działa, ale dołączono to, aby zakończyć zadanie: cat /tmp/srv-input | myserver; kill -9 cat / tmp / srv-input-cat-pid` && rm / tmp / srv-input-cat * `
Thiago Macedo
4

Tak jak powyżej, ale „kot” nie działał dla mnie. Plik otrzymał EOF i zakończył się po wysłaniu jednego polecenia.

To działało dla mnie:

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &
Tamir
źródło