Mam długo działający proces serwera w sesji ekranowej na moim serwerze Linux. Jest to trochę niestabilne (i niestety nie moje oprogramowanie, więc nie mogę tego naprawić!), Więc chcę skrypty co noc restartować proces, aby poprawić stabilność. Jedynym sposobem na sprawne zamknięcie jest przejście do procesu wyświetlania ekranu, przejście do okna, w którym działa, i wpisanie ciągu „stop” na konsoli sterowania.
Czy są jakieś sprytne przekierowania, które mogę zrobić, aby cronjob wysyłał komendę stop o określonej godzinie każdego dnia?
ls -l /proc/7417/fd/0
./dev/pts/19
),y
Znak nie dociera do samej aplikacji. Jest to podobne do tego, co dzieje się po użyciu polecenia write (1) . W każdym razie albo wypróbuj moją inną odpowiedź, albo narzędzie do automatyzacji grafiki, takie jak xdotool .Rozwiązanie oparte na ekranie
Uruchom serwer w następujący sposób:
ekran uruchomi się w trybie odłączonym, więc jeśli chcesz zobaczyć, co się dzieje, uruchom:
Kontroluj serwer w następujący sposób:
(ta odpowiedź opiera się na wysyłaniu wprowadzania tekstu na odłączony ekran ze strony rodzeństwa Unix i Linux )
Objaśnienie parametrów:
rozwiązanie oparte na tmux
Uruchom serwer w następujący sposób:
tmux uruchomi się w trybie odłączonym, więc jeśli chcesz zobaczyć, co się dzieje, uruchom:
Kontroluj serwer w następujący sposób:
Objaśnienie parametrów:
źródło
Spróbuj tego, aby rozpocząć:
A to zabić:
źródło
echo "xxx" > cmd
program zatrzyma się (ponieważ rura zostanie zamknięta). Chociaż niektóre programy są wystarczająco inteligentne, aby ponownie otworzyć (rewind(3)
) swoje standardowe wejście, gdy napotkają EOF.Możliwe jest wysyłanie tekstu wejściowego do uruchomionego procesu bez uruchamiania
screen
narzędzia lub innego wymyślnego narzędzia. Można tego dokonać, wysyłając ten tekst wejściowy do „standardowego” pliku wejściowego procesu/proc/PID#/fd/0
.Jednak tekst wejściowy musi zostać przesłany w specjalny sposób, aby został odczytany przez proces. Wysłanie tekstu wejściowego zwykłą
write
metodą pliku nie spowoduje, że proces odbierze tekst. Wynika to z tego, że spowoduje to dołączenie tylko do tego „pliku”, ale nie uruchomi procesu odczytu bajtów.Aby uruchomić proces odczytu bajtów, konieczne jest wykonanie
IOCTL
operacji typuTIOCSTI
dla każdego wysłanego bajtu. Spowoduje to umieszczenie bajtu w standardowej kolejce wejściowej procesu.Jest to omówione tutaj z kilkoma przykładami w C, Perl i Python:
https://unix.stackexchange.com/questions/48103/construct-a-command-by-putting-a-string-into-a-tty/48221
-
Aby odpowiedzieć na pierwotne pytanie zadane prawie 9 lat temu, zadanie crona musiałoby uruchomić mały skrypt / program narzędziowy podobny do przykładów, które ludzie napisali dla tego innego pytania, które wysyłałyby ciąg „stop \ n” do tego procesu serwera w pytaniu, wysyłając każdy z 5 bajtów za pomocą
IOCTL
operacji typuTIOCSTI
.Oczywiście będzie to działać tylko w systemach obsługujących
TIOCSTI
IOCTL
typ operacji (takich jak Linux) i tylko zroot
konta użytkownika, ponieważ te „pliki” poniżej/proc/
są „własnością”root
.źródło
Na wypadek, gdyby komukolwiek to pomogło:
miałem podobny problem, a ponieważ proces, którego używałem, nie był zbyt niski
screen
lubtmux
musiałem zastosować inne podejście.Podłączyłem się
EDYTOWAĆgdb
do tegoxterm
, w którym działał mój proces, i użyłemcall write(5, "stop\n", 5)
odgdb
do zapisu do głównego deskryptora pliku pty.Dowiedziałem się, do którego deskryptora pliku wysłać dane, szukając
/proc/<pid>/fd
linku,/dev/ptmx
a następnie próbując i popełniając błąd między tymi dwiema opcjami (wysyłanie mojego ciągu do obu pasujących deskryptorów plików wydawało się nie powodować szkód).Okazało się, że
EDYCJA KOŃCOWAxterm
proces, do którego się przyłączyłem, został odrodzony zspawn-new-terminal()
xterm
akcją z klawiszem, a drugiptmx
otwarty deskryptor pliku był po prostu procesemptmx
nadrzędnymxterm
, który nie został zamknięty.Stąd wywołania prób i błędów wysłały dane wyjściowe do tego drugiego terminala.
Większość
xterm
procesów nie ma dwóchptmx
deskryptorów plików.To skutecznie wpisało ten ciąg do terminala, a tym samym wysłało go do uruchomionego pod nim procesu.
Uwaga: może być konieczne zezwolenie na dołączenie do uruchomionego procesu za pomocą czegoś takiego
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
źródło
Ponieważ nie mogę skomentować najbardziej akceptowanej odpowiedzi Cristiana Ciupitu (z 2010 r.), Muszę umieścić to w osobnej odpowiedzi:
To pytanie zostało już rozwiązane w tym wątku: https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-external-process
W skrócie:
Musisz rozpocząć proces od potoku dla stdin, który nie blokuje ani nie zamyka się, gdy bieżące wejście zostało zapisane. Można to zaimplementować za pomocą prostej nieskończonej pętli, która zostanie potokowana do danego procesu:
Mogę potwierdzić, że jest to inny sposób krissiego na otwarcie fajki, która nie działała w moim przypadku. Pokazane rozwiązanie działało zamiast tego.
Następnie możesz napisać do pliku ... / fd / 0 procesu, aby wysłać do niego instrukcje. Jedyną wadą jest to, że musisz zakończyć proces bash, który wykonuje pętlę nieskończoną po zamknięciu serwera.
źródło