다른 bash 세션에서 실행중인 프로세스의 출력을 보는 방법은 무엇입니까?


199

로컬에서 작업 할 때부터 원격 컴퓨터에서 스크립트를 실행했습니다. SSH를 통해 동일한 사용자로 컴퓨터에 연결할 수 있으며에서 실행되는 스크립트를 볼 수 ps있습니다.

$ ps aux | grep ipcheck
myuser  18386  0.0  0.0  18460  3476 pts/0    S+   Dec14   1:11 /bin/bash ./ipchecker.sh

로컬 세션에서 stdout으로 출력하는 것입니다 ( ./ipchecker.sh로컬 터미널 창에서 리디렉션, 리디렉션 없음 screen등을 실행했습니다).

어쨌든 SSH 세션 에서이 실행중인 명령의 출력을 볼 수 있습니까 (중지하지 않고)?

지금까지 내가 찾은 최선의 방법은 사용하는 strace -p 18386것이지만 화면에 너무 많은 텍스트가 표시되어 너무 상세합니다. 나는 strace출력을 멈추고 체로 걸러서 stdout에 인쇄 된 텍스트를 찾을 수 있지만 길고 혼란 스럽습니다. 정지 된 동안 분명히 뭔가를 놓칠 수 있습니다. 로컬에서 작업하는 것처럼 스크립트 출력을 실시간으로 볼 수있는 방법을 찾고 싶습니다.

누구든지 이것을 개선 할 수 있습니까? 확실한 대답은 리디렉션이나 screen세션 등으로 스크립트를 다시 시작하는 것입니다. 이것은 미션 크리티컬 스크립트가 아니므로 그렇게 할 수 있습니다. 오히려, 나는 이것을 재미있는 학습 연습으로 본다.


프로세스가 가상 콘솔 또는 GUI / xterm과 같은 환경에서 실행되고 있습니까?
jippie

4
strace의 출력을 하나의 syscall로 제한 할 수 있습니다.strace -p 4232 -e write
otokan

@jippie 머신이 전체 GUI (Linux Mynt 13, XFCE 데스크탑)를 실행 중이며 그놈 터미널을 시작했습니다.
jwbensley

3
이 사이트에는 적어도 12 가지의 유사한 질문이 있습니다. 를 찾아 reptyr 그들 중 몇 가지 (과 답변)을 보려면 여기를.
Stéphane Chazelas

답변:


180

기존 프로세스를 스파이하려는 경우 strace -p1234 -s9999 -e write1234는 프로세스 ID입니다. ( -s9999문자열이 32 자로 잘리지 않도록하고 write출력을 생성하는 시스템 호출을 피하십시오.) 특정 파일 디스크립터에 기록 된 데이터 만 보려면 strace -p1234 -e trace= -e write=3파일 디스크립터 3에 기록 된 데이터 만 보는 것과 같은 것을 사용할 수 있습니다 ( -e trace=시스템 방지 통화 기록). 그것은 이미 생산 된 출력을 제공하지 않습니다.

출력이 너무 빨리 스크롤되는 경우,와 같은 호출기로 파이프하거나을 사용 less하여 파일로 보낼 수 strace -o trace.log …있습니다.

많은 프로그램을 사용하면 ptrace 핵을 사용하여 후속 출력을 현재 터미널 또는 새 화면 세션으로 전환 할 수 있습니다. 실행중인 프로세스를 제거하고 새 화면 셸에 연결하는 방법을 참조하십시오 . 그리고 다른 연결된 스레드.

시스템 설정 방법에 따라 strace추가 권한없이 사용자가 프로세스를 실행하더라도 이러한 모든 명령을 루트 로 실행해야 할 수도 있습니다 . 프로세스가 다른 사용자로 실행 중이거나 setuid 또는 setgid 인 경우 strace루트 로 실행해야 합니다. 대부분의 배포는 프로세스가 하위 프로세스 만 추적하도록 허용합니다 (이는 중간 정도의 보안 이점을 제공합니다. 파일을 수정하여 간접 주입을 방지하지는 않습니다). 이것은 kernel.yama.ptrace_scomesysctl에 의해 제어됩니다 .


18
출력을 표준 출력 으로 좁히는 방법이 있다고 생각하지 않습니다 .
요나

3
모든 주장을 설명 할 수 있습니까?
사용자

6
nodejs에서 얻은 많은 출력에 많은 백 슬래시와 숫자가있었습니다. 그들이 어떤 인코딩을 할 수 있습니까? 많은 평범한 텍스트도 있었는데, 내가 필요한 전부였습니다.
ThorSummoner

3
"모든 논증을 설명 할 수 있습니까?" @User :man strace
Pistos

3
@RafaelMoni 당신이 요구하는 것을하는 프로그램을 디버거라고합니다.
Gilles

139

proc파일 시스템을 통해 출력에 액세스 할 수 있습니다 .

tail -f /proc/<pid>/fd/1

1= stdout, 2= stderr


7
'읽기 위해 / proc / <my pid> / fd / 1을 열 수 없습니다 : 해당 장치 또는 주소가 없습니다'.
Yaroslav Nikitenko

18
예 <my pid>는 프로세스 ID
tvlooy

29
출력이 tty로 이동하거나으로 리디렉션되는 /dev/null경우에는 작동하지 않습니다. 출력이 파일로 리디렉션 된 경우에만 작동합니다.
mattdm

1
우분투 16.04에서 테스트되었으며 작동하지 않습니다. 세션에서 나는 : ping google.es루트로 다른 것을 tail -f /proc/`pgrep ping`/fd/2하고 아무것도 표시되지 않습니다.
david.perez

1
네 말이 맞아 fd 1과 2는 / dev / pts 장치에 대한 심볼릭 링크이므로 pts 장치를 테일링 할 수 없습니다. ping 명령을 cronjob으로 예약 한 다음 동일하게 수행하십시오. tail -f는 다음 작동합니다
tvlooy

9

BSD에서는 watch어떤 tty를 주어진 tty로 사용할 수 있습니다.

watch /dev/pts/0

Linux에서는 screen또는 과 같은 전에 멀티플렉서에서 프로세스를 실행하지 않은 경우에는 불가능합니다 tmux. 참조 : Reptyr : 실행중인 프로세스를 새 터미널에 연결

(예를 들면 유일한 방법은 프로세스를 디버깅하는 것 strace, dtrace/ dtruss, gdb, lldb, 등).

을 사용 strace하여 의미있는 출력을 가져 오려면 정규 표현식 (예 :)으로 필터링 한 file다음 출력을 구문 분석해야합니다. 예를 들면 다음과 같습니다.

strace -e trace=write -s1000 -fp 18386 2>&1 | grep -o '".\+[^"]"'

PID가 지정한 프로세스의 쓰기 작업 (길이 1000) ( pgrep이름으로 찾는 데 사용) 을 인쇄하고 표준 오류를 출력 (필터링)으로 리디렉션하고 큰 따옴표로 묶인 문자열을 인쇄합니다.

이진 출력을 다루는 경우 read(with -r) 및 printf (with %b) 를 사용하여 이스케이프 시퀀스 문자를 구문 분석 할 수 있습니다.

while read -r -t1 line; do printf "%b" $line; done

help read더 많은 매개 변수를 확인하십시오 (예 : -n줄 바꿈이 아닌 특정 문자 수 후에 인쇄).

보다 완벽한 예는 다음과 같습니다.

strace -e trace=write -s1000 -fp 18386 2>&1 \
| grep --line-buffered -o '".\+[^"]"' \
| grep --line-buffered -o '[^"]\+[^"]' \
| while read -r line; do
  printf "%b" $line;
done

프로세스를 사용하는 예를 보려면 다음을 확인하십시오. 쉘의 strace를 일반 텍스트로 구문 분석하는 방법은 무엇입니까? 스택 오버 플로우


4
  1. ssh localhost 'DISPLAY=:0.0 xwd -root' | xwud -scalewhere localhost는 원격 서버 로그인 자격 증명으로 대체되고 :0.0GUI의 표시 번호로 원격 화면을 들여다 볼 수 있습니다 .

  2. 사용 x11vnc화면에 X-세션에 대한 VNC 서버입니다.

  3. 6 개의 가상 콘솔 중 하나에서 실행할 때 적절한 vc로 sudo setterm -dump 2 -file /dev/stdout바꾸십시오 2.


4

명명 된 파이프 ( mkfifo)를 만든 다음 해당 파일에 쓰는 것이 좋습니다. 그런 다음 읽어보십시오. tail출력을 최소화하기 위해, 등으로 항상 그렇게 할 수 있습니다 . 파이프를 읽을 때 (파이프에서 읽을 때마다) 지워 지므로 출력이 유지되지 않습니다.

다른 옵션은 모든 것을 파일 (로그 파일과 유사)에 쓴 다음 언제든지 분석하는 것입니다. 모든 출력을 유지하려는 경우 선호되는 조치입니다.


3

당신은 항상 nohup& 프로세스를 시작할 수 있습니다

nohup rsync source_file dest_file &

그런 다음 모든 tty에서 진행 상황을 확인할 수 있습니다.

tail -f nohup.out

이것은 나에게 잘 작동합니다.


6
이 질문은 귀하의 답변에서 알 수 있듯이 백그라운드에서 프로세스를 실행하는 방법이 아니라 경고 실행 프로세스의 출력을 보는 방법에 대한 것입니다.
jwbensley

사실, 당신의 : nohup 언급은 나를 밝힙니다! 감사!
Nam G VU

1

출력을 얻는 매우 간단한 방법은 출력을 파일로 캡처하고 해당 파일을 마무리하는 것입니다.

해야 할 경우 : ./ipcheck

INSTEAD DO : ./ipcheck> [파일 이름으로 교체]

스크립트가있는 출력 파일이 생성됩니다. 그런 다음 다른 bash 쉘에서 간단히 파일을 꼬리말로 붙일 수 있습니다.

tail [파일 이름으로 대체] -f


파일 리디렉션은 기본적으로 블록 기반 버퍼링을 사용하는 경향이 있으며 (참조 setbuf(3)) tail문제 를 일으킬 수 있습니다 .
thrig

5
또한 이것은 새로운 프로세스를 위해 stdout을 리디렉션하는 방법이 아니라 이미 실행중인 프로세스의 출력을 보는 방법에 관한 질문에 도움이되지 않습니다.
jwbensley

1

strace 출력 파싱 :

내가 사용 최고 대답을 (내 공정 28,223의 ID와) ...

> sudo strace -p28223 -s9999 -e write
...
write(9, "Info\nI\nCare\nabout", 55) = 55
...

내가 관심이 있는지 확인합니다 write(9. (9는 아래에서 사용되며 아마도 파일 핸들 일 것이고 프로세스에 따라 다를 수 있습니다.) 그런 다음 구문을 분석하고 표시하는 빠른 Ruby 스크립트를 작성했습니다.

다음을 붙여 넣기 /usr/bin/parse_strace.rb

#!/usr/bin/ruby

num = ARGV[0]
STDIN.each { |line|
  if (line.match(/write\(#{ num },\s*"(.*?)"/)) then
    puts $1.split('\x').map { |s| s.to_i(16).chr }.join()
  end
}

잊지 마세요 chmod a+x /usr/bin/parse_strace.rb

첫 번째 인수로 strace -xx스크립트에 STDERR을 포함하여 파이핑 (16 진수를 출력하므로 정규 표현식이 올바르게 일치 함)을 호출 9합니다.

sudo sh -c 'strace -xx -p28223 -s9999 -e write 2>&1 | parse_strace.rb 9'

그리고 voila는 프로세스의 원래 STDOUT, 줄 바꿈, 색상 및 모든 것을 출력합니다!

STDOUT 처리에 첨부


0

프로세스 ID를 받아서 USR1과 통신 할 수 없습니다.

$pgrep -l '^ipchecker.sh$'

스크립트의 PID를 인쇄 한 다음이를 사용하여

$ kill -USR1 PID

USR1은 "사용자 정의"신호라는 것을 이해합니다. 프로그램을 만든 사람은 누구나 "종료"또는 "로그를 덤프"또는 "foo를 천 번 인쇄"또는 무엇이든 의미 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.