Vraag Kan ik wat tekst naar de STDIN sturen van een actief proces dat wordt uitgevoerd in een schermsessie?


Ik heb een langlopend serverproces in een schermsessie op mijn Linux-server. Het is een beetje onstabiel (en helaas niet mijn software, dus dat kan ik niet oplossen!), Dus ik wil een nachtelijke herstart van het proces schrijven om stabiliteit te bevorderen. De enige manier om er een sierlijke afsluiting van te maken, is door naar het schermproces te gaan, over te schakelen naar het venster waarin het draait en de string "stop" in te voeren op de bedieningsconsole.

Zijn er slimme omleidingen die ik kan doen om een ​​cronjob elke dag op een vast tijdstip het stopcommando te laten sturen?


61
2017-09-06 11:42


oorsprong




antwoorden:


Dit antwoord lost het probleem niet op, maar het blijft hier omdat 30+ mensen het nuttig vonden, anders zou ik het lang geleden al hebben verwijderd.

Schrijven aan /proc/*pid of the program*/fd/0. De fd subdirectory bevat de descriptors van alle geopende bestanden en bestandsdescriptor 0 is de standaard invoer (1 is stdout en 2 is stderr).

U kunt dit gebruiken om berichten uit te voeren op de tty waar een programma wordt uitgevoerd, maar u kunt niet naar het programma zelf schrijven.

Voorbeeld

Terminal 1:

[ciupicri@hermes ~]$ cat
shows on the tty but bypasses cat

Terminal 2:

[ciupicri@hermes ~]$ pidof cat
7417
[ciupicri@hermes ~]$ echo "shows on the tty but bypasses cat" > /proc/7417/fd/0

78
2017-09-06 12:06



@James Lawrie: kijk dan eens naar proc (5) en proc.txt. - Cristian Ciupitu
+2 maakt niet uit hoeveel je denkt dat je weet, er is altijd meer te leren :) glad. - troyengel
Houd er echter rekening mee dat de proc fd alleen doorverwijst naar wat wordt gebruikt als een bron van stdin. In uw voorbeeld, als u iets in terminal 1 invoert, zal het het opnieuw afdrukken (het wordt naar katten gestuurd, stdin en cat print het af), waardoor u het twee keer ziet. Aan de andere kant als je iets naar fd / 0 stuurt, wordt het naar de console gestuurd, maar niet naar de kat, en dus slechts een keer weergegeven. Omdat de kat eenvoudig de invoer opnieuw afdrukt met dit voorbeeld, kun je niet echt zien of je invoer of uitvoer wordt afgedrukt, dus deze misvatting. / fd / 0 wijst naar de console / pts; zien ls -l /proc/7417/fd/0. - Kissaki
voorbeeld uit de praktijk: ik heb gphoto2 --get-all-files gestart en vraagt ​​100 keer om een ​​bevestiging. Wanneer ik "y"> / proc / PID / fd / 0 herhaal, gaat gphoto2 niet verder, maar "y" wordt afgedrukt in de terminal. - Thorsten Staerk
@ThorstenStaerk, ik weet het, daarom heb ik die notitie toegevoegd. U schrijft alleen naar het apparaatbestand dat overeenkomt met de terminal waarop de gphoto2 wordt uitgevoerd (bijv. /dev/pts/19), de y karakter bereikt de applicatie zelf niet. Het is vergelijkbaar met wat er gebeurt als je de schrijven (1) commando. Hoe dan ook, probeer mijn andere antwoord of een grafische automatiseringstool zoals xdotool. - Cristian Ciupitu


Op scherm gebaseerde oplossing

Start de server als volgt:

# screen -d -m -S ServerFault tr a-z A-Z # replace with your server

scherm start in de losstaande modus, dus als u wilt zien wat er gebeurt, voert u het volgende uit:

# screen -r ServerFault

Beheer de server als volgt:

# screen -S ServerFault -p 0 -X stuff "stop^M"
# screen -S ServerFault -p 0 -X stuff "start^M"
# screen -S ServerFault -p 0 -X stuff "^D" # send EOF

(dit antwoord is gebaseerd op het verzenden van tekstinvoer naar een vrijstaand scherm van de Unix en Linux broers en zussen site)

Uitleg van de parameters:

-d -m
   Start screen in "detached" mode. This creates a new session but doesn't
   attach to it.  This is useful for system startup scripts.
-S sessionname
   When creating a new session, this option can be used to specify a meaningful
   name for the session.
-r [pid.tty.host]
-r sessionowner/[pid.tty.host]
   resumes a detached screen session.
-p number_or_name|-|=|+
   Preselect a window. This is useful when you want to reattach to a specific
   window or you want to send a command via the "-X" option to a specific
   window.
-X
   Send the specified command to a running screen session e.g. stuff.

spul [draad]

   Stuff the string string in the input  buffer of the current window.
   This is like the "paste" command but with much less overhead.  Without
   a parameter, screen will prompt for a string to stuff.

op tmux gebaseerde oplossing

Start de server als volgt:

# tmux new-session -d -s ServerFault 'tr a-z A-Z' # replace with your server

tmux start in de losstaande modus, dus als u wilt zien wat er gebeurt, voert u het volgende uit:

# tmux attach-session -t ServerFault

Beheer de server als volgt:

# tmux send-keys -t ServerFault -l stop
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault -l start
# tmux send-keys -t ServerFault Enter
# tmux send-keys -t ServerFault C-d # send EOF

Uitleg van de parameters:

 new-session [-AdDP] [-c start-directory] [-F format] [-n window-name] [-s
         session-name] [-t target-session] [-x width] [-y height]
         [shell-command]
         Create a new session with name session-name.

         The new session is attached to the current terminal unless -d is
         given.  window-name and shell-command are the name of and shell
         command to execute in the initial window.  If -d is used, -x and
         -y specify the size of the initial window (80 by 24 if not
         given).

 send-keys [-lR] [-t target-pane] key ...
               (alias: send)
         Send a key or keys to a window.  Each argument key is the name of
         the key (such as `C-a' or `npage' ) to send; if the string is not
         recognised as a key, it is sent as a series of characters.  The
         -l flag disables key name lookup and sends the keys literally.

34
2017-10-19 01:08





Probeer dit om te starten:

# screen
# cd /path/to/wd
# mkfifo cmd
# my_cmd <cmd
C-A d

En dit om te doden:

# cd /path/to/wd
# echo "stop" > cmd
# rm cmd

4
2017-09-06 12:03



Dit is goed, maar het kan het nadeel hebben dat het niet in staat is om andere commando's te verzenden terwijl het programma draait. Als het programma stopt wanneer het EOF op stdin raakt en vervolgens op de eerste echo "xxx" > cmd het programma stopt (omdat de pijp wordt gesloten). Hoewel sommige programma's slim genoeg zijn om opnieuw te openen (rewind(3)) hun stdin wanneer ze EOF tegenkomen. - Cristian Ciupitu


Als het iemand helpt:
Ik had een soortgelijk probleem, en omdat het proces dat ik gebruikte niet onder was screen of tmux, Ik moest een andere benadering kiezen.

Ik bevestigde gdb naar de xterm dat mijn proces actief was en werd gebruikt call write(5, "stop\n", 5) van gdb om te schrijven naar de master pty file descriptor.
Ik ontdekte naar welke bestandsdescriptor de gegevens moeten worden verzonden door ernaar te kijken /proc/<pid>/fd voor een link naar /dev/ptmx en vervolgens vallen en opstaan ​​tussen de twee opties (het verzenden van mijn string naar beide overeenkomende bestandsdescriptors leek geen schade aan te richten).

BEWERK

Het bleek dat de xterm proces waar ik aan gehecht was, werd voortgebracht door de spawn-new-terminal()  xterm actie van een toetsing, en de tweede ptmx bestandsdescriptor open was gewoon de ptmx van de ouder xterm proces dat niet was afgesloten.
Vandaar dat de trial and error-oproepen output naar die andere terminal hadden gestuurd.
Meest xterm processen hebben er geen twee ptmx bestandsbeschrijvingen.

EINDE BEWERKEN

Dit typte die snaar effectief in de terminal en stuurde deze daarom naar het onderliggende proces.

N.B. je moet misschien toestaan ​​dat je je vastmaakt aan een lopend proces met zoiets
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"


1
2017-12-31 09:42