W powłoce można wykonać przekierowanie >
<
itp., Ale co powiesz PO uruchomieniu programu?
Oto, jak przyszedłem zadać to pytanie: program działający w tle mojego terminala ciągle wyświetla irytujący tekst. To ważny proces, więc muszę otworzyć inną powłokę, aby uniknąć tekstu. Chciałbym mieć możliwość >/dev/null
lub inne przekierowanie, abym mógł dalej pracować w tej samej powłoce.
Odpowiedzi:
Oprócz zamykania i ponownego otwierania terminala (tj. Wylogowania się i ponownego zalogowania, co może również zakończyć niektóre procesy w tle), pozostaje tylko jedna możliwość:
na przykład:
$ 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
Możesz również rozważyć:
screen
; screen udostępnia kilka wirtualnych TTY, między którymi można się przełączać bez konieczności otwierania nowych sesji SSH / telnet / etcnohup
; umożliwia to zamknięcie i ponowne otwarcie sesji bez utraty procesów w tle w procesie ...źródło
open("/path/to/new/stdout",O_WRONLY)
. O_WRONLY prawdopodobnie nie będzie jednak dostępny; jego wartość znajduje się1
w systemie Linux / glibc.1025
aktywuje , co jest przydatne, jeśli przekierowujesz zarówno stderr, jak i stdout do tego samego pliku.O_APPEND
O_WRONLY
To wystarczy:
strace -ewrite -p $PID
Nie jest tak czysty (pokazuje linie takie jak:)
write(#,<text you want to see>)
, ale działa!Może Ci się również nie spodobać fakt, że argumenty są skrócone. Aby kontrolować, użyj
-s
parametru, który ustawia maksymalną długość wyświetlanych ciągów.Przechwytuje wszystkie strumienie, więc możesz chcieć to jakoś przefiltrować:
strace -ewrite -p $PID 2>&1 | grep "write(1"
pokazuje tylko wywołania deskryptora 1.
2>&1
jest przekierowanie STDERR do STDOUT, ponieważstrace
domyślnie zapisuje do STDERR.źródło
sudo
jest to potrzebne.nabijając się na doskonałych badaniach vladr (i innych):
utwórz następujące dwa pliki w tym samym katalogu, coś w swojej ścieżce, powiedz $ HOME / bin:
silence.gdb, zawierający (z odpowiedzi vladr):
p dup2(open("/dev/null",0),1) p dup2(open("/dev/null",0),2) detach quit
i cisza zawierająca:
#!/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
Teraz następnym razem, gdy zapomnisz przekierować na przykład Firefoksa, a Twój terminal zacznie się zaśmiecać komunikatami nieuniknionymi „(firefox-bin: 5117): Gdk-WARNING **: kolizja XID, problemy z wyprzedzeniem”:
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
Możesz również przekierować wyjście gdb do / dev / null, jeśli nie chcesz go widzieć.
źródło
--batch-silent
która blokuje wyjście i nie zrzuca cię do konsoli gdb, jeśli coś pójdzie nie tak (np. Brak procesu). BTW,$!
odnosi się do ostatniego zadania w tle, ale nie sądzę, aby można go było użyć w samym skrypcie. Używam aliasu:alias silencebg='silence $!'
Przekieruj dane wyjściowe z uruchomionego procesu do innego terminala, pliku lub ekranu:
Wewnątrz gdb :
p close(1) p open("/dev/pts/4", 1) p close(2) p open("/tmp/myerrlog", 1) q
Odłącz działający proces od terminala bash i utrzymuj go przy życiu:
[Ctrl+z] bg %1 && disown %1 [Ctrl+d]
Wyjaśnienie:
20818 - przykład uruchomionego procesu pid
p - wypisuje wynik polecenia gdb
close (1) - zamknij standardowe wyjście
/ dev / pts / 4 - terminal do zapisu do
zamknięcia (2) - zamknij wyjście błędu
/ tmp / myerrlog - plik do zapisz do
q - wyjdź z gdb
bg% 1 - uruchom zatrzymane zadanie 1 w tle
wykluczone% 1 - odłącz zadanie 1 od terminala
źródło
stdin
(deskryptor pliku0
) jest zamknięty.p open("/tmp/myerrlog", 2)
?Nie jest to bezpośrednia odpowiedź na twoje pytanie, ale jest to technika, którą uważam za przydatną przez ostatnie kilka dni: uruchom początkowe polecenie za pomocą „screen”, a następnie odłącz.
źródło
jest to część skryptu basha oparta na poprzednich odpowiedziach, która przekierowuje plik dziennika podczas wykonywania otwartego procesu, jest używany jako postscript w
logrotate
procesie#!/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
źródło
https://www.isi.edu/~yuri/dupx/
źródło
Możesz użyć reredirect ( https://github.com/jerome-pouiller/reredirect/ ).
Rodzaj
a wyjścia (standardowe i błędne) zostaną zapisane w PLIKU.
reredirect README wyjaśnia również, jak przywrócić pierwotny stan procesu, jak przekierować do innej komendy lub przekierować tylko stdout lub stderr.
reredirect
dostarcza również skrypt o nazwie,relink
który umożliwia przekierowanie do bieżącego terminala:(wydaje się, że reredirect ma te same cechy, co Dupx opisany w innej odpowiedzi, ale nie zależy od Gdb).
źródło