stdin을 통해 명령을 받을 수 있는 Linux 애플리케이션을 디버깅하려고 하는데 stdin에 기록된 모든 내용을 볼 수 있으면 매우 유용할 것입니다.
내 첫 번째 접근 방식은 을 실행하는 것이 었지만 내 프로세스와 프로세스가 모두 해당 파일 설명자의 내용을 소비하려고 했고 오직 하나의 프로세스만이 경쟁에서 승리할 수 있었기 sudo cat /proc/$pid/fd/0
때문에 이는 비효율적인 접근 방식임이 입증되었습니다 .cat
또 다른 방법은 tail을 사용하는 것이지만 다음과 같은 이유로 작동하지 않습니다.여기.
내 애플리케이션에 디버그 로깅을 쉽게 추가하면 문제가 해결될 것입니다. 하지만 제가 놓친 보다 일반적인 접근 방식이 있는지 알고 싶습니다.
답변1
strace
?
아래 예. stdin을 읽고 /tmp/foofile에 쓰는 cat 프로세스를 시작합니다. pid를 찾아 추적하세요. 원래 고양이 창에 Hey, Come on이라는 텍스트를 입력합니다.
# cat >/tmp/foofile
# ps -ef|grep cat
steve 2134 1801 0 22:25 pts/2 00:00:00 cat
# strace -fp 2134
Process 2134 attached
read(0, "test\n", 65536) = 5
write(1, "test\n", 5) = 5
read(0,
파일 설명자 0에서 읽으려면:
strace -fp 2134 -e trace=read -o "|grep read.0,"
답변2
Linux에서는 애플리케이션의 파일 설명 자를 /dev/fd/[0-9]
.tee
그리고표준 출력으로. 그렇다면 나는 당신의 상황에 처했을 때 보통 무엇을 합니까?(늘 그렇듯)내 독서 응용 프로그램 이며 tee
- stderr에 대한 입력입니다 /dev/fd/2
.
이와 같이:
seq 10 | tee /dev/fd/2 | wc -c
1
2
3
4
5
6
7
8
9
10
21
물론 Linux 시스템을 사용하지 않더라도 포팅을 통해 동일한 작업을 수행할 수 있습니다. 경우에 따라 덜 구체적이라면 다음과 같이 하십시오....| tee /dev/tty | ...
터미널 얘기라면stdin
(링크에 표시된대로), 커널의 라인 버퍼링으로 인해 이 방법이 더 까다로울 수 있지만 아마도 여전히 동일한 작업을 수행할 것입니다. 따라서 이 경우 내가 할 일은 tty
내 명령을 래핑하여 모든 I/O를 기록하는 것 입니다 luit
. 두 가지 중 더 편리하다고 생각하기 때문에 script
거의 동일한 방식으로 작동할 수도 있습니다.
luit
아마도 시스템에 이미 설치되어 있을 것입니다. 일반적으로 함께 패키지되어 있습니다 xterm
. UTF-8 변환을 수행하도록 설계된 매우 간단한 cli 도구입니다.(cli 스위치를 통해 기능을 완전히 비활성화하는 것이 가능하지만 그렇게 할 이유를 찾지 못했습니다)그것을 이해하지 못하는 터미널 애플리케이션의 경우.
현재 tty 계층 아래에 자체 pty(기본 fd를 소유)를 계층화하고 현재 세션의 모든 I/O를 요청한 응용 프로그램이 실행되는 하위 계층으로 복사하는 방식으로 작동합니다. 마스터를 소유하기 때문에 읽고 쓰는 모든 I/O를 다른 곳에서 쉽게 복제할 수 있으며 그렇게 하도록 요청할 수 있는 편리한 방법을 제공합니다.
luit -olog /dev/fd/2 sh -c 'read var; echo "$var"'
eecchhoo tthhiiss vvaarr??????
echo this var???
echo this var???
보시다시피 모든 터미널 입력은 luit
일단 수신되면 명명된 파일에 기록됩니다.-olog
이 경우에는 /dev/fd/2
모든 I/O가 동일한 위치에서 두 번 발생하므로 를 사용하는 것이 그다지 유용하지 않습니다. 나는 일반적으로 두 번째 터미널을 열고 명령을 사용하여 이름을 쿼리 tty
하고 해당 이름을 / 에 대한 명명된 출력 파일 /dev/pts/[0-9]
로 사용하는 것을 선호합니다 . 이렇게 하면 모든 I/O가 두 터미널에 동시에 복사되므로 하나의 터미널에서 읽을 수 있습니다. 그것을 가져가거나 보고 반대편에서 상호 작용하십시오. 대부분의 경우 동일한 작업을 수행하는 데 사용할 수 있지만 일반적으로 pty의 주요 측면에서 권장하는 이점이 없습니다.luit
script
tee
귀하의 목적이 귀하의 검토를 위해 일부 프로세스에 모든 입력을 복사하는 것이라면 입력에 집중하는 것이 더 나을 것입니다. strace
이는 많은 경우에 유용하지만 일반적인 동작에 대한 정확한 보고서를 얻으려면 보고서를 수집할 때 해당 동작을 가능한 한 적게 수정해야 하는 것이 합리적입니다. 즉, 입력이 필요한 경우 입력을 복사하고 디버그 상위 프로세스를 삽입하지 마십시오. 그러면 -TRAP
시스템 호출이 이루어질 때마다 프로세스가 일시 중지됩니다.
답변3
한 가지 가능성(이것이 다른 문제를 중단하지 않는 경우)에 호출을 삽입하는 것입니다.tee
. 이 명령은 tee
데이터를 복사하므로 복사본 하나는 애플리케이션으로 보내고 하나는 디버그 출력으로 보낼 수 있습니다. 전화하지 말고 your_application
통화 일정을 잡으세요 tee input.log | your_application
. 애플리케이션에 대한 입력이 파일인 경우 이는 침입적인 변경이 아니지만 파이프가 아닌 경우 결과적으로 파이프가 됩니다(예: 파이프를 검색할 수 없음).
또 다른 가능성은 애플리케이션이 수행하는 파일 읽기 작업을 추적하는 것입니다. 당신은 이것을 할 수 있습니다스트레스:
strace -e read=0 -e trace=read -e signal=none your_application 2>&1 |
grep '^ |'