Befehl nohup tail mit Umleitung in einem Shell-Skript, das in einer bestimmten Situation nicht ordnungsgemäß aufgerufen wird

1286
Neha Sharma

Ich habe ein Problem, bei dem ein Tail-Befehl im Bash-Skript nicht korrekt funktioniert, wenn er von remote aufgerufen wird, indem er nur einen Parameter von 2 Params bereitstellt. Aber es funktioniert richtig, wenn:

  • direkt auf lokal mit 1 param ausgeführt
  • direkt auf lokal mit 2 params ausgeführt
  • von fern mit 2 params ausgeführt

Ich habe unten ein Skript geschrieben, das mit follow beginnt. Es sind 2 Parameter erforderlich:

  1. TESTNAME: Dieser Parameter ist obligatorisch. Dies ist der Name des Testfalls. Es erstellt eine Protokolldatei mit diesem Namen.
  2. SLAVE_HOST: Dieser Parameter ist optional. Wenn angegeben, wird die SSH an den bereitgestellten Slave-Host gesendet und ein ähnliches Skript darauf gestartet.

    #!/bin/bash TESTNAME="$1"  testdate=$(date +'%m_%d_%Y') REG_DIR=/opt/reg-test-results/REG_"$testdate"  #create regression results directory if it does not exist mkdir -p "$REG_DIR"  FILENAME="$REG_DIR"/"$TESTNAME"  #if file already exists, create a new one with current time stamp appended to name if [ -f "$FILENAME" ]; then TIME=$(date +'%m_%d_%Y-%H.%M.%S') FILENAME="$FILENAME"_"$TIME" fi  echo "$FILENAME" > /opt/reg-test-results/currentTestName  #start tailing nohup tail -f -n0 /path/to/log/files/*/*server.log > "$FILENAME" & echo "$!" > $REG_DIR/reg_tail.pid  #if slave host is provided, start tailing logs on slave also if [ "$#" -gt 1 ]; then SLAVE_HOST="$2" ssh "$SLAVE_HOST" /path/to/script/startTailLogTestCaseSlave.sh "$FILENAME" fi 

Die ersten Codezeilen speichern Parameter in Variablen. Erstellen Sie eine Verzeichnisstruktur und einen Dateinamen für die Protokolldatei, in die die Protokolle mit dem Endpunkt geleitet werden. Danach habe ich den Befehl nohup tail, um das Protokollieren von Protokollen zu starten und in die Protokolldatei zu leiten. Dies ist die Codezeile, die nicht ordnungsgemäß funktioniert. Wenn das zweite Argument angegeben wurde, wird es an diesen Host gesendet und ein Befehl darauf ausgeführt.

Problem: Beim Ausführen von Remote und dem Übergeben beider Parameter wird nach der Ausführung dieses Skripts ein Endprozess ausgeführt, und die Protokolldatei wird ordnungsgemäß mit Inhalt gefüllt. Wenn ich jedoch nur den ersten Parameter zur Verfügung stelle, sieht es so aus, als würde er tail beginnen und sofort stoppen, da in der Datei reg_tail.pid eine neue Prozess-ID angezeigt wird, die Protokolldatei ($ FILENAME) jedoch nicht erstellt wird und kein Tail-Prozess ausgeführt wird.

Das Skript läuft perfekt mit 1 Parameter oder beiden, wenn es direkt auf dem Computer ausgeführt wird.

Mit "beim Ausführen von Remote" meine ich ssh auf die Maschine und rufe das Skript auf. Für zB:

$ ssh -t user@host /path/to/script/script.sh testcasename.log 

Debugging-Aufwand:

Folgendes sehe ich, wenn ich set -x verwende und von einem entfernten Rechner aus laufe:

Wenn das zweite Argument übergeben wird und alles normal läuft, sehe ich, dass am Ende nohup tail ausgeführt wird.

 .... + echo 13441 + '[' 2 -gt 1 ']' + SLAVE_HOST=slaveHost + ssh slaveHost /path/to/script/startTailLogTestCaseSlave.sh /opt/reg-test- results/REG_09_11_2015/logs2.log + nohup tail -f -n0 /path/to/logs/../check-server.log ... nohup: redirecting stderr to stdout Connection to hostname closed. 

Wenn nur das erste Argument übergeben wird, wird nohup-tail nie ausgeführt:

 ... + echo 13607 + '[' 1 -gt 1 ']' Connection to hostname closed. 
-2
(1) Wow. Sie sind bei hostA angemeldet und geben "ssh hostB scriptname filename hostC" ein. Das Skript ruft * `ssh hostC scriptname filename 'auf. Vielleicht möchten Sie einen Schritt zurücktreten und sehen, ob Sie Ihr Design vereinfachen können. (2) Das Skript zeigt den Befehl `tail` vor dem` ssh "$ SLAVE_HOST"… `- Befehl - aber die Diagnoseausgabe 'set -x' zeigt` tail 'nach `ssh'. Möchten Sie das erklären? (3) Sie sollten immer Shell-Variablen angeben, es sei denn, Sie haben einen guten Grund, dies nicht zu tun, und Sie sind sich sicher, dass Sie wissen, was Sie tun. Scott vor 9 Jahren 0
Warum brauchen Sie überhaupt "nohup"? Ich denke, das könnte in diesem Fall mit den Ausgabedateibeschreibern zu schaffen machen. Breakthrough vor 9 Jahren 0
Danke euch allen. @Scott, notiert # 1. Vielen Dank. Über # 2 ist dies die Reihenfolge, die ich sehe. Ich kenne den Grund nicht. Schwanz wird immer am Ende ausgeführt, wenn ich im zweiten Argument weitergebe. Ich habe viele Variationen ausprobiert, z. B. einen String mit dem Wert "null" für SLAVE_HOST übergeben und die Bedingung nicht ssh hinzugefügt, wenn der Wert "null" ist. Es startet nur tail, wenn der Befehl ssh ausgeführt wird, und startet tail nach ssh, obwohl der Befehl tail vor ssh liegt. Über # 3 wurde mein Code so aktualisiert, dass er immer Anführungszeichen verwendet. Neha Sharma vor 9 Jahren 0
@Breakthrough, das Entfernen von nohup hat nicht geholfen. Neha Sharma vor 9 Jahren 0
@NehaSharma Warum hast du überhaupt 'nohup' hinzugefügt? Erklärungen könnten hier zur Fehlersuche beitragen. Abgesehen davon, wenn Sie dasselbe Verhalten ohne "nohup" erhalten, hat dies nichts mit Ihrem speziellen Problem / Ihrer Frage zu tun. Breakthrough vor 9 Jahren 0
@Breakthrough, ich fügte es hinzu, weil, wenn ich es ferngesteuert habe, der Tail-Befehl manchmal nicht funktionierte, aber manchmal war es. Ich wusste nicht den Grund, aber ich habe nur nachgesehen und sieht so aus, als wäre die Antwort hier: https://en.wikipedia.org/wiki/Nohup Dort steht: "Beachten Sie, dass eine abschließende SSH-Sitzung nicht immer ein HUP-Signal sendet zu abhängigen Prozessen " Neha Sharma vor 9 Jahren 0
@NehaSharma Sind Sie sicher, dass der Befehl nicht ausgeführt wird und stattdessen einfach nicht angezeigt wird (z. B. nachdem Sie das Skript ausgeführt haben, obwohl die Zeile `nohup tail 'nicht angezeigt wird?), Ist die Ausgabe in` $ FILENAME "dort wenigstens)? Breakthrough vor 9 Jahren 0
@Breakthrough, ja ich bin mir sicher. Was ich gesehen hatte, war, dass die Pid for Tail, die von meinem Skript in reg_tail.pid geschrieben wurde, jedes Mal eine neue PID druckte. Als ich jedoch den Prozess nach pid nachgesehen oder nach einem "tail -f" -Prozess gesucht habe, war keiner vorhanden. So wurde ein Prozess erstellt und getötet. Die Ausgabedatei $ FILENAME wurde ebenfalls nicht erstellt. Neha Sharma vor 9 Jahren 0

1 Antwort auf die Frage

0
Neha Sharma

Ich habe das Problem durch Hinzufügen eines Delay-after-Tail-Befehls behoben.

nohup tail -f -n0 /path/to/log/files/*/*server.log > "$FILENAME" 2> test.err < /dev/null & echo "$!" > "$REG_DIR"/reg_tail.pid  #without this delay, the above tail command is not being executed when only one 1 argumet is passed sleep 1  #if slave host is provided, start tailing logs on slave also if [ "$#" -gt 1 ]; then 

Ich habe mich gefragt, warum es funktioniert, nachdem der Befehl ssh ausgeführt wurde, obwohl er nicht verwandt ist. Also entschied ich mich, eine Verzögerung hinzuzufügen. Ich bin zwar kein Experte, aber es sieht aus wie ein Rennzustand. Der Tail-Hintergrundprozess wurde so geplant, dass er am Ende ausgeführt wird. In dem Fall, in dem kein ssh-Befehl ausgeführt wurde, wurde das Skript beendet und die Sitzung wurde beendet, bevor der Tail-Prozess eine Chance zur Ausführung erhielt. Wenn der Hauptprozess in den Ruhezustand versetzt wird, besteht die Möglichkeit, den Prozess (oder den Thread) zu beenden. Ich bin mir nicht sicher, ob diese Lösung die beste ist. Wenn ich warten wende statt schlafe, bleibt es hängen, weil "tail -f" weiter läuft. Ich verwende dieses Skript, um Protokolle zu beenden und dann einen Testfall auszuführen. Nachdem die Testfallausführung abgeschlossen ist, führe ich ein anderes Skript aus, das die PID des Schwanzes von dort abliest, wo es gespeichert ist und den Schwanz tötet.