반응형

출처

https://www.baeldung.com/linux/redirect-output-of-running-process

이미 실행중인 프로세스의 출력을 redirecting 하기

1. 소개

Linux에서 작업할 때 redirections을 사용하는 것은 매우 일반적입니다. 예를 들어, 프로그램을 실행할 수 있고 실행시 생성되는 출력을 침묵시킬 수 있습니다. 그러나 bash는 프로세스가 실행되면 출력을 redirection 하는 직접적인 방법을 제공하지 않습니다. 따라서 이 글에서는 실행중인 프로세스의 출력을 리디렉션하거나 복사하는 다양한 방법에 대해 알아 봅니다. 예를 들어 프로그램을 실행할 때 출력을 리디렉션하는 것을 잊은 경우 유용 할 수 있습니다.

이를 위해 첫 번째는 gdb를 사용하고 다른 하나는 strace를 사용하며 마지막으로 세 번째는 screen을 사용하는 세 가지 방법을 살펴 보겠습니다. 세 번째 접근 방식은 약간 다릅니다.

2. 출력을 redirect하기 위해 gdb 사용하기

gdb_는 리눅스에서 코드 디버깅을 위한 강력한 도구입니다. 그리고 우리는 실행 중인 프로세스에서 코드를 실행하기 위해 그것을 사용할 수 있습니다. 이 경우, *_우리는 실행 중인 프로세스로 _gdb_에 접근(attach)하여 출력을 redirect하기 위해 *gdb 사용할 것이며 작업을 마쳤을 때 실행중인 프로세서로부터 분리(detach)할 것입니다.**

출력을 redirect하기 위해 우리가 할 수 있는 방법은 현재 파일 descriptor를 닫고 그것을 새로운 출력을 가리키도록 다시 여는 것입니다. 우리는 opendup2 함수를 사용하여 이를 할 것입니다.

유닉스 시스템에는 2개의 기본 출력이 있는데, 표준출력*과 *표준에러 입니다. _표준출력_은 파일 descriptor 1과 관련되어 있고 _표준에러_는 파일 descriptor 2와 관련되어 있습니다. 예를 들어, 표준 출력을 redirect하기 원하면 우리는 파일 descriptor 1에서 활동할 필요가 있습니다.

우리는 PID 14560인 프로세스의 출력을 redirect하기 원한다고 가정합시다. 우리는 그 PID로 _gdb_를 접근함으로써 시작해야 합니다.

$ gdb -p 14560

프로세스로 접근했을 때 우리는 파일 descriptor 1을 /tmp/process_stdout로 redirect할 수 있습니다.

(gdb) p dup2(open("/tmp/process_stdout", 1089, 0777), 1)

우리는 숫자 1089를 사용했는데 이는 _O_WRONY | O_CREAT | O_APPEND_를 표현하기 때문이라는 것을 참고하세요.

우리는 표준 출력도 같은 방법으로 파일 descriptor 2를 사용함으로써 정확하게 redirect할 수 있습니다.

(gdb) p dup2(open("/tmp/process_stderr", 1089, 0777), 2)

이 시점에서 출력이 redirect 되었습니다. 그러나 프로세스가 중지되고 _gdb_가 그 프로세스에 접근(attach)합니다.

더 이상 gdb가 필요하지 않으므로 프로세스에서 분리하고 _gdb_를 종료할 수 있습니다. 이렇게하면 프로세스가 계속 실행됩니다.

(gdb) q

또는 /dev/null로 redirect 하여 출력을 침묵시킬 수 있습니다.

(gdb) p dup2(open("/dev/null"), 1)

우리는 모든 gdb 명령을 "명령 파일"로 작성할 수 있고 파라미터 -x 를 사용하여 그것을 실행할 수 있습니다.
gdb_redirect 라 불리는 파일을 생성합시다.

p dup2(open("/tmp/process_stdout", 1089, 0777), 1)
p dup2(open("/tmp/process_stderr", 1089, 0777), 2)
q

다음 우리의 파일 _gdb_redirect_를 사용하여 _gdb_를 실행하면 됩니다.

$ gdb -p 14560 -x gdb_redirect

3. 모든 쓰기 호출을 검사하는 strace 사용하기

우리는 시스템 콜(호출)을 검사하는 strace를 사용할 수도 있습니다. 이 방법은 원래 출력을 중단하지 않습니다. 대신 다른 위치로 복사합니다.
PID 14560의 표준 오류로 쓰는 모든 쓰기를 검사합시다.

$ strace -etrace=write -s 100000 -p 14560 2>&1 | grep --line-buffered '^write(2,'
write(2, "\r", 1)                       = 1
write(2, "17243001856 bytes (17 GB, 16 GiB) copied, 1185 s, 14.6 MB/s", 59) = 59
write(2, "\r", 1)                       = 1
write(2, "17249965568 bytes (17 GB, 16 GiB) copied, 1186 s, 14.5 MB/s", 59) = 59

이 파라미터로 strace*는 *쓰기 호출과 최대 문자열 크기를 10만으로 설정하여 PID 14560에 접근합니다. 그리고 우리는 파일 descriptor 2로 쓰는 것만 출력하기 위해 grep 으로 사용합니다.
우리는 /tmp/process_stderr라 불리는 파일로 이를 redirect할 수 있습니다.

$ strace -etrace=write -s 100000 -p 14560 2>&1 | grep --line-buffered '^write(2,' > /tmp/process_stderr

만약 strace 출력 포멧을 좋아하지 않는다면 문자열만 출력하기 위해 sed를 사용할 수 있습니다.

$ strace -etrace=write -s 100000 -p 14560 2>&1 | sed -n -r 's/^write\(2,\s*"(.+)",\s*[[:digit:]]+\)\s*=\s*[[:digit:]]+$/\1/p'
\r
25754656256 bytes (26 GB, 24 GiB) copied, 1710 s, 15.1 MB/s
\r
25761747456 bytes (26 GB, 24 GiB) copied, 1711 s, 15.1 MB/s

또한 ** strace는 16진수와 파일 descriptor로 쓰여진 아스키코드로 출력할 수 있습니다.** 우리는 이를 -ewrite=fd 옵션을 사용하여 할 수 있습니다.

$ strace -ewrite=2 -etrace=write -p 14560 2>&1 | grep  --line-buffered '^ |'
 | 00000  0d                                                .                |
 | 00000  33 33 30 31 32 30 32 37  39 30 34 20 62 79 74 65  33012027904 byte |
 | 00010  73 20 28 33 33 20 47 42  2c 20 33 31 20 47 69 42  s (33 GB, 31 GiB |
 | 00020  29 20 63 6f 70 69 65 64  2c 20 32 31 36 32 20 73  ) copied, 2162 s |
 | 00030  2c 20 31 35 2e 33 20 4d  42 2f 73                 , 15.3 MB/s      |
 | 00000  0d                                                .                |
 | 00000  33 33 30 31 39 36 32 31  38 38 38 20 62 79 74 65  33019621888 byte |
 | 00010  73 20 28 33 33 20 47 42  2c 20 33 31 20 47 69 42  s (33 GB, 31 GiB |
 | 00020  29 20 63 6f 70 69 65 64  2c 20 32 31 36 33 20 73  ) copied, 2163 s |
 | 00030  2c 20 31 35 2e 33 20 4d  42 2f 73                 , 15.3 MB/s      |

4. screen을 사용하여 파일에 출력 쓰기

프로세스가 스크린 세션 내에서 실행 중인 경우 현재 창을 파일에 기록할 수 있습니다. strace와 마찬가지로 출력을 대체하지 않고 대신 복사합니다. 그러나 임의의 파일 descriptor를 복사 할 수 없습니다. 화면 창에 기록 중인 내용만 복사할 수 있습니다.

이를 위해 screen 명령 로그 또는 핫키 C-a H를 사용합니다. 그러면 화면 창 번호가 n 인 screenlog.n이라는 파일에 로깅이 활성화됩니다. 그런 다음 화면에서 분리하여 프로세스를 실행하면 screenlog.n에서 출력을 볼 수 있습니다. log 명령이나 핫키를 다시 사용하여 언제든지 로그인을 중지 할 수 있습니다.

또한 logfile 명령을 사용하여 출력을 작성할 위치를 지정할 수 있습니다.

:logfile process_output

그런 다음 log를 실행하면 출력이 screenlog.n 대신 process_output에 표시됩니다.

동영상 링크

5. 결론

이 글에서는 이미 실행중인 프로세스의 출력을 redirect 하는 세 가지 방법을 살펴 보았습니다.

먼저 gdb를 사용하여 현재 출력을 새 출력으로 대체했습니다. 그런 다음 *strace로 *쓰기 위한 모든 호출을 가로 채서 원하는 출력을 다른 위치에 복사했습니다. 마지막으로 창을 파일에 기록하는 screen을 활용했습니다.

반응형
반응형

출처 

http://unix.stackexchange.com/questions/163352/what-does-dev-null-21-mean-in-this-article-of-crontab-basics

http://blogger.pe.kr/369

crontab에 관한 글에서 '>/dev/null 2>&1'의 뜻이 무엇인가요?

crontab에 관한 글을 읽고 있습니다.

다음은 자동으로 이메일 보내는 것을 불가능하게 하는 방법에 대한 내용입니다.

8.  이멩일 불가능하게 하기 

기본으로 cronjob을 실행하는 사용자 계정으로 이메일을 보냅니다. 이것이 필요하지 않으면 shell 명령어 끝에 다음 명령을 붙이세요.

>/dev/null 2>&1

2> & ,  1 의 자세한 뜻이 무엇입니까? cronjob 파일의 마지막에 이메일 보내는 것을 끄기 위해 왜 이걸 붙어야 합니까?

-------------

6개의 답변 중 1개의 답변만 추려냄.

>  리다이렉트(redirect)를 위한 것입니다. 

역자 설명) 화면에 출력된 내용(stdout)을 오른쪽에 나올 파일(여기서는 /dev/null)로 결과를 보내라는 뜻입니다.

/dev/null 은 어떤 데이터를 보내든 블랙홀로써 전부 버려질 것입니다.

2 는 표준 에러를 뜻하는 파일 디스크립터(file descriptor) 입니다.

>  리다이렉트(redirect)를 위한 것입니다. 

& 파일 디스크립터를 뜻하는 심볼입니다. (이 기호가 없으면 다음 1 은 파일이름으로 간주될 것입니다.)

1 은 표준 출력을 뜻하는 파일 디스크립터(file descriptor) 입니다.

그러므로 >/dev/null 2>&1 는 프로그램의 출력을 /dev/null로 보냅니다(redirect). 보낼 때 표준에러 와 표준출력이 포함됩니다.

더 많은 정보를 원하시면 리눅스 문서화 프로젝트 페이지 I/O Redirection 에서 확인 가능합니다.

cron 은 job의 출력이 있을 때만 이메일을 당신에게 보낼 것입니다. null로 redirect되는 모든 것에 대해 출력이 없기 때문에 cron은 당신에게 이메일을 보내지 않을 것입니다.



반응형

+ Recent posts