it-swarm.com.de

STDERR/STDOUT eines Prozesses NACH dem Start über die Befehlszeile umleiten?

In der Shell können Sie Umleitung, >< usw. durchführen, aber wie wäre es, nachdem ein Programm gestartet wurde?

So kam ich zu dieser Frage: Ein Programm, das im Hintergrund meines Terminals ausgeführt wird, gibt störenden Text aus. Dies ist ein wichtiger Prozess, daher muss ich eine andere Shell öffnen, um den Text zu vermeiden. Ich möchte >/dev/null oder eine andere Umleitung, damit ich in derselben Shell weiterarbeiten kann.

108
Ian Kelling

Wenn Sie Ihr tty schließen und erneut öffnen (d. H. Sich abmelden und wieder einschalten, wodurch möglicherweise einige Ihrer Hintergrundprozesse im Prozess abgebrochen werden), haben Sie nur noch eine Wahl:

  • verbinden Sie sich mit gdb mit dem betreffenden Prozess und führen Sie Folgendes aus:
    • p dup2 (open ("/ dev/null", 0), 1)
    • p dup2 (open ("/ dev/null", 0), 2) 
    • ablösen
    • verlassen

z.B.:

$ tail -f /var/log/lastlog &
[1] 5636

$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/pts/0
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog

$ gdb -p 5636
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Attaching to process 5636
Reading symbols from /usr/bin/tail...(no debugging symbols found)...done.
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0x7f3c8f5a66e0 (LWP 5636)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2

(no debugging symbols found)
0x00007f3c8eec7b50 in nanosleep () from /lib/libc.so.6

(gdb) p dup2(open("/dev/null",0),1)
[Switching to Thread 0x7f3c8f5a66e0 (LWP 5636)]
$1 = 1

(gdb) p dup2(open("/dev/null",0),2)
$2 = 2

(gdb) detach
Detaching from program: /usr/bin/tail, process 5636

(gdb) quit

$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/null
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
lr-x------ 1 myuser myuser 64 Feb 27 07:36 4 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 5 -> /dev/null

Sie können auch in Betracht ziehen:

  • using screen; screen bietet mehrere virtuelle TTYs, zwischen denen Sie wechseln können, ohne neue SSH/Telnet/etc-Sitzungen öffnen zu müssen
  • using Nohup; Dadurch können Sie Ihre Sitzung schließen und erneut öffnen, ohne dabei Hintergrundprozesse im Prozess zu verlieren.
110
vladr

Das wird es tun:

strace -ewrite -p $PID

Es ist nicht so sauber (zeigt Zeilen wie: write(#,<text you want to see>)), funktioniert aber!


Sie mögen auch die Tatsache, dass Argumente abgekürzt werden, nicht mögen. Um dies zu steuern, verwenden Sie den -s-Parameter, der die maximale Länge der angezeigten Zeichenfolgen festlegt.

Es fängt alle Streams ein, so dass Sie das irgendwie filtern möchten:

strace -ewrite -p $PID 2>&1 | grep "write(1" 

zeigt nur Deskriptor 1-Aufrufe. 2>&1 soll STDERR zu STDOUT umleiten, da strace standardmäßig in STDERR schreibt.

55
naugtur

wladr (und andere) hervorragende Forschung riffing:

erstellen Sie die folgenden zwei Dateien in demselben Verzeichnis, etwas in Ihrem Pfad, sagen Sie $ HOME/bin:

silence.gdb, enthaltend (aus vladrs Antwort):


p dup2(open("/dev/null",0),1)
p dup2(open("/dev/null",0),2)
detach
quit

und Stille, bestehend aus:


#!/bin/sh
if [ "$0" -a "$1" ]; then
 gdb -p $1 -x $0.gdb
else
 echo Must specify PID of process to silence >&2
fi

chmod +x ~/bin/silence  # make the script executable

Wenn Sie beispielsweise das nächste Mal vergessen, Firefox umzuleiten, wird Ihr Terminal mit dem Unvermeidlichen unübersichtlich "(firefox-bin: 5117): Gdk-WARNING **: XID-Kollision, Ahead Ahead":


ps  # look for process xulrunner-stub (in this case we saw the PID in the error above)
silence 5117  # run the script, using PID we found

Sie können auch die Ausgabe von gdb nach/dev/null umleiten, wenn Sie es nicht sehen möchten.

18
jcomeau_ictx

Umleiten der Ausgabe von einem laufenden Prozess an ein anderes Terminal, eine andere Datei oder einen anderen Bildschirm:

tty
ls -l /proc/20818/fd
gdb -p 20818

Innerhalb gdb :

p close(1)
p open("/dev/pts/4", 1)
p close(2)
p open("/tmp/myerrlog", 1)
q

Trennen Sie einen laufenden Prozess von bash terminal und halten Sie ihn am Leben:

[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]

Erläuterung:

20818 - nur ein Beispiel für die Ausführung von Prozess-PIDs
p - Ergebnis des Befehls gdb drucken
close (1) - Standardausgabe schließen
/dev/pts/4 - Terminal zum Schreiben
close (2) - Fehlerausgabe schließen
/tmp/myerrlog - Datei, in die geschrieben werden soll
q - gdb beenden
bg% 1 - Job 1 wurde im Hintergrund gestoppt
disown% 1 - Job 1 vom Terminal trennen

14
Mirek

Keine direkte Antwort auf Ihre Frage, aber es ist eine Technik, die ich in den letzten Tagen für nützlich befunden habe: Führen Sie den ersten Befehl mit 'screen' aus und trennen Sie ihn dann.

3
Roger Lipscombe

dies ist ein auf früheren Antworten basierender Bash-Skriptteil, der die Protokolldatei während der Ausführung eines offenen Prozesses umleitet. Sie wird als Postscript inlogrotateprocess verwendet

#!/bin/bash

pid=$(cat /var/run/app/app.pid)
logFile="/var/log/app.log"

reloadLog()
{
    if [ "$pid" = "" ]; then
        echo "invalid PID"
    else
        gdb -p $pid >/dev/null 2>&1 <<LOADLOG
p close(1)
p open("$logFile", 1)
p close(2)
p open("$logFile", 1)
q
LOADLOG
        LOG_FILE=$(ls /proc/${pid}/fd -l | fgrep " 1 -> " | awk '{print $11}')
        echo "log file set to $LOG_FILE"
    fi
}

reloadLog
2
Mostafa Nazari

Sie können reredirect ( https://github.com/jerome-pouiller/reredirect/ ) verwenden.

Art

reredirect -m FILE PID

und Ausgaben (Standard und Fehler) werden in DATEI geschrieben.

reredirect README erläutert auch, wie Sie den ursprünglichen Prozessstatus wiederherstellen, zu einem anderen Befehl umleiten oder nur stdout oder stderr umleiten.

reredirect bietet auch ein Skript namens relink, mit dem Sie auf das aktuelle Terminal umleiten können:

relink PID
relink PID | grep usefull_content

(reredirect scheint die gleichen Funktionen zu haben wie Dupx, die in einer anderen Antwort beschrieben wurden, es hängt jedoch nicht von Gdb ab).

0
Jezz

Dupx ist ein einfaches * nix-Dienstprogramm zum Umleiten der Standardausgabe eingabe/-fehler eines bereits laufenden Prozesses.

/ - https://www.isi.edu/~yuri/dupx/

0
eMPee584