[linux] 명령 행을 사용하여 시작된 후 프로세스의 STDERR / STDOUT을 리디렉션 하시겠습니까?

쉘에서 리디렉션 > <등을 수행 할 수 있지만 프로그램을 시작한 후에는 어떻습니까?

다음은이 질문을하는 방법입니다. 터미널 백그라운드에서 실행되는 프로그램은 계속 성가신 텍스트를 출력합니다. 중요한 과정이므로 텍스트를 피하기 위해 다른 쉘을 열어야합니다. 할 수 있기를 원합니다>/dev/null같은 쉘에서 계속 작업 할 수 있도록 다른 리디렉션이나 다른 리디렉션 .



답변

tty를 닫았다가 다시 열지 못하는 경우 (즉, 로그 오프했다가 다시 로그온하면 프로세스의 일부 백그라운드 프로세스가 종료 될 수 있음) 한 가지만 선택할 수 있습니다.

  • gdb를 사용하여 해당 프로세스에 연결하고 다음을 실행하십시오.
    • p dup2 (열기 ( “/ dev / null”, 0), 1)
    • p dup2 (열기 ( “/ dev / null”, 0), 2)
    • 떼다
    • 떠나다

예 :

$ 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

다음을 고려할 수도 있습니다.

  • 사용하여 screen; 화면은 새로운 SSH / telnet / etc, 세션을 열지 않고도 전환 할 수있는 여러 가상 TTY를 제공합니다.
  • 사용하여 nohup; 이를 통해 프로세스의 백그라운드 프로세스를 잃지 않고 세션을 닫았다가 다시 열 수 있습니다.

답변

이것은 할 것이다 :

strace -ewrite -p $PID

그것은 깨끗하지는 않지만 (와 같은 줄을 보여줍니다 write(#,<text you want to see>)) 작동합니다!


또한 인수가 생략된다는 사실을 싫어할 수도 있습니다. 그것을 사용하여 제어하려면-s표시되는 최대 문자열 길이를 설정 매개 변수 .

모든 스트림을 포착하므로 어떻게 든 필터링 할 수 있습니다.

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

설명자 1 호출 만 표시합니다. STDERR에 기본적 2>&1으로 strace쓰듯이 STDERR 을 STDOUT으로 리디렉션 하는 것입니다.


답변

vladr (및 다른 사람들)의 훌륭한 연구를 수행 :

동일한 디렉토리에 다음 두 파일을 작성하십시오 (예 : $ HOME / bin).

silence.gdb, (vladr의 답변에서) :


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

그리고 침묵 :


#!/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

이제 다음에 파이어 폭스를 리디렉션하는 것을 잊어 버렸을 때 터미널은 피할 수없는 “(firefox-bin : 5117) : Gdk-WARNING ** : XID 충돌, 문제가 발생했습니다”라는 메시지로 인해 혼란스럽게 시작합니다.


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

보고 싶지 않은 경우 gdb의 출력을 / dev / null로 리디렉션 할 수도 있습니다.


답변

실행중인 프로세스에서 다른 터미널, 파일 또는 화면으로 출력을 리디렉션하십시오.

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

내부 gdb :

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

bash 터미널 에서 실행중인 프로세스를 분리하고 활성 상태로 유지하십시오.

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

설명:

20818-프로세스 pid
p 실행 예-gdb 명령의 인쇄 결과
close (1)-표준 출력 닫기
/ dev / pts / 4-
닫기 에 쓸 터미널 (2)-닫기 오류 출력
/ tmp / myerrlog-파일
q에 쓰기 -종료 gdb
bg % 1-백그라운드 제거 % 1에서 중지 된 작업 1 실행
-터미널에서 작업 1 분리


답변

귀하의 질문에 대한 직접적인 대답은 아니지만 지난 며칠 동안 유용하다고 생각한 기술입니다. ‘screen’을 사용하여 초기 명령을 실행 한 다음 분리하십시오.


답변

이것은 오픈 프로세스 실행 중 로그 파일을 리디렉션하는 이전 답변을 기반으로하는 bash 스크립트 부분이며 logrotate프로세스 에서 포스트 스크립트로 사용됩니다

#!/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


답변

Dupx 는 이미 실행중인 프로세스의 표준 출력 / 입력 / 오류를 리디렉션하는 간단한 * nix 유틸리티입니다.

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