Ctrl + c in einem Unterprozess beendet einen Prozess, der zuvor nicht im Skript war

4265
Hashbrown

Ich wusste nicht, ob dies zu SO gehörte (da es sich um einen Codierungsfehler handelt), aber ich dachte, Ihr Jungs wäre besser informiert über die Feinheiten der verwendeten Software (daher könnte sogar U & L in Betracht gezogen werden).

Hier ist das minimale Codeskript (siehe Bearbeitungen für vollständiges Skript, es gibt einen Grund, warum ich es so mache);

#/bin/bash nohup > currentOutput.log 2>&1 &  less +F currentOutput.log 

Es wird versucht, einen Server im Hintergrund auszuführen, der in eine Protokolldatei ausgegeben wird.
Dann followbenutze ich diese Logdatei less +F. Um dies zu beenden, müssen Sie ctrl+ drücken, cbevor Sie einen Treffer erzielen können Q.

Was passiert ist, wenn ich ctrl+ cinnerhalb des lessBefehls (zum Stoppen tailing) es irgendwie den Server tötet, nohupder oben mit gestartet wurde ! Nichts anderes ist betroffen. Ich kann shift+ fdas Protokoll erneut starten (was keine neuen Informationen erhält, da der Server beendet ist) und wenn ich Qden Rest des Skripts durchführe, wird es normal ausgeführt.

Weißt du warum das passiert? Wie vermeide ich es / etwas anderes sollte ich verwenden?


PS
Das Serverprogramm wartet möglicherweise auf a ^C, was möglicherweise das Problem ist. Kann ich etwas dagegen tun? Wenn ich einfach alleine renne (blockierend), kann ich ctrl+ schlagen c, was es nicht sofort tötet; es druckt Received ^C signal, shutting down(und tötet sich dann selbst). Dies passiert, wenn ich ^Cin less(Ein Finale Received ^C signal, shutting downwird in das Protokoll geschrieben).


PPS
Ich habe eine Reihe von Dingen ausprobiert (keine hat funktioniert);

  • Versuch, das stdin durch Ändern vom Skript zu trennen

    nohup > currentOutput.log 2>&1 & to nohup echo '' | > currentOutput.log 2>&1 & or nohup cat /dev/null/ | > currentOutput.log 2>&1 & 
  • mit stty intr ^Gersetzen, um den Interrupt-Befehl zu ersetzen, aber dann ctrl+ gtat genau das, was ^Cohnehin getan wurde (daher könnte dies ein Problem mit meinem Terminalemulator sein; konsole)

  • das nohup& / oder die lessZeile in Klammern setzen (um es zu einer Subshell zu machen)

  • Ausführen des Skripts xtermanstelle vonkonsole

13
Jemand hat vielleicht mein Problem (http://www.linuxquestions.org/questions/programming-9/ignore-disable-ctrl-c-sigint-in-a-shell-script-780188/) entdeckt; "Ich denke, es liegt an der Handhabung innerhalb der Datenbanksoftware, nicht an der Shell." Wie würde ein Programm das tun? Wie könnte ich es dann aufhalten? Hashbrown vor 10 Jahren 0
"nohup" verhindert, dass der Prozess ein "SIGHUP" -Signal empfängt, während CTRL + C ein "SIGINT" -Signal sendet. Deshalb hat `nohup` nicht den erwarteten Effekt. Piotr Dobrogost vor 9 Jahren 3

2 Antworten auf die Frage

9
Hashbrown

Ich war zu Recht in der Annahme, dass es SIGINTzu allen Prozessen gesendet wurde, wenn ctrl+ c, aber ich war dumm, zu glauben, dass ein anderer Prozess den Vorgang außerhalb des Bereichs bringen würde process group(siehe meine Versuche in P.P.S.).

Dies ist nicht nur der genaue Anwendungsfall, sondern auch die richtige Lösung.

Aufgrund der Strukturierung meines Skripts passte die Antwort dort nicht wörtlich, dies ist jetzt das Skript.

#/bin/bash  setsid > currentOutput.log 2>&1 & less +F currentOutput.log 

Der Server gibt nach I ctrl+ cin weiterhin die Protokolldatei aus less.

Vielen Dank für alle Zeit.

0
MariusMatutiae

Hast du versucht, dich abzuwenden ?

 disown -h %1 

oder was auch immer dein Job ist; disown ist eine integrierte Shell, die Manpage besagt:

verleugnen

disown [-ar] [-h] [jobspec ...]

Ohne Optionen wird jede Auftragsspezifikation aus der Tabelle der aktiven Aufträge entfernt. Wenn die Option -h' option is given, the job is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If jobspec is not present, and neither the-a 'nor -r' option is supplied, the current job is used. If no jobspec is supplied, the-a' bedeutet, alle Jobs zu entfernen oder zu markieren; Die Option -r ohne Jobspec-Argument beschränkt den Vorgang auf die Ausführung von Jobs.

BEARBEITEN

Witzige Sache, dein Bau funktioniert auf meinem Arch Linux:

 $ cat testm #!/bin/sh  nohup /home/mario/temp/waste &   less +F out.log  $ cat waste #!/bin/sh  while [ 1 ]; do find / -print 2>1 1> out.log done $ ./testm nohup: appending output to ‘nohup.out’ $ ps ax | grep waste 19090 pts/2 S 0:00 /bin/sh /home/mario/temp/waste 19124 pts/2 S+ 0:00 grep waste] $ 

Vor dem ps Befehl hatte ich die out.log Datei zu blättern, dann Ctrl+C, dann q.

ja, aber ich weiß nicht, wie ich es anwenden soll. Ich habe versucht, die "nohup" -Linie in einer Funktion zu platzieren, die sich selbst "disowns", aber das sollte das gleiche wie "nohup" sein. Ich denke nicht, dass dies ein SIGHUP-Problem ist, denn wenn ich die Zeile "weniger" entferne, endet das Skript mit dem laufenden Server Hashbrown vor 10 Jahren 0
@Hashbrown pls sehen meine Bearbeitung MariusMatutiae vor 10 Jahren 0
Ja, ich habe auch einen Test gemacht, mit einem einfachen Bash-Skript, das anstelle der ausführbaren Datei aufgerufen wird. Und nohup hat einfach gut funktioniert. Sehen Sie meinen Kommentar zur Frage. Ich denke es hört absichtlich irgendwie zu. Da es ein guter (und nicht allseits bekannter) Server ist, kann ich nicht sagen, was es ist, also kann jemand "oh sein X machen, Sie müssen Y machen" Hashbrown vor 10 Jahren 0