다른 명령의 출력과 지정된 문자열이 인쇄될 때를 모니터링하는 도구가 필요합니다. 모니터링되는 명령을 중지하려면 "오류"가 발생합니다. 그런 다음 일부 환경과 파일을 수정하고 계속 작업합니다. 가능합니까?
편집: 예:
다음과 같은 job.sh가 있습니다.
for i in $(ls)
do
echo file $i
sleep 0.1
cat $i
done
a.txt 및 b.txt 파일이 포함된 폴더에서 실행할 때 file b.txt
편집을 위해 job.sh를 인쇄한 후 일시 중지한 다음 job.sh를 계속하여 새 b.txt 콘텐츠를 확인하고 싶습니다. job.sh는 실제로 컴파일된 C 프로그램이기 때문에 건드릴 수 없습니다. 수면은 즉각적일 필요는 없지만 빨라야 하는 일시정지를 상징합니다.
답변1
% ./mystery
a
b
c
%
STOP
프로그램에 신호를 보낸 다음 실행을 계속할 수 있습니다 CONT
. 다음 TCL 코드는 b
출력이 나타날 때까지 기다린 다음 프로세스를 중지합니다. 프로세스는 사용자가 expect_user
실행할 줄(적어도 개행 문자)을 입력할 때까지 중지된 상태로 유지되어야 합니다.
#!/usr/bin/env expect
spawn -noecho ./mystery
set spid [exp_pid]
expect -ex b { exec kill -STOP $spid; send_user "STOP\n" }
expect_user -re . { exec kill -CONT $spid }
expect eof
물론 여기에는 mystery
너무 빠르게 실행되거나 출력이 버퍼링되는 등 모든 종류의 문제가 있습니다. 문제를 해결하려면 C 속도를 늦추고 버퍼링을 꺼야 했습니다.
% cat mystery.c
#include <stdio.h>
#include <unistd.h>
int main(void)
{
setvbuf(stdout, (char *) NULL, _IONBF, (size_t) 0);
printf("a\n");
sleep(1);
printf("b\n");
sleep(1);
printf("c\n");
return 0;
}
예를 들어 gdb
, 중단점은 I/O에 반응하는 것보다 코드의 특정 지점에서 실행을 중지하는 더 정확한 방법입니다. 디버그 기호는 도움이 되지만 필수는 아닙니다.
% gdb mystery
Reading symbols from mystery...(no debugging symbols found)...done.
(gdb) quit
% otool -dtv mystery | grep callq
0000000100000f26 callq 0x100000f70
0000000100000f32 callq 0x100000f6a
0000000100000f3c callq 0x100000f76
0000000100000f48 callq 0x100000f6a
0000000100000f52 callq 0x100000f76
0000000100000f5e callq 0x100000f6a
따라서 이것은 실제로 Mac에 있습니다(분해는 플랫폼에 따라 다릅니다). 위의 내용은 setvbuf
, printf
, sleep
호출 및 시작 주소 입니다.
% otool -dtv mystery | sed 3q
mystery:
_main:
0000000100000f06 pushq %rbp
% perl -E 'say 0x0000000100000f52 - 0x0000000100000f06'
76
% gdb mystery
Reading symbols from mystery...(no debugging symbols found)...done.
(gdb) b *main + 76
Breakpoint 1 at 0x100000f52
(gdb) r
Starting program: /Users/jhqdoe/tmp/mystery
a
b
Breakpoint 1, 0x0000000100000f52 in main ()
(gdb)
그런 다음 필요한 모든 작업을 수행하고 필요에 따라 프로그램을 계속할 수 있습니다.
LD_PRELOAD
또 다른 아이디어는 가장 현명한 옵션(소스에서 프로그램을 다시 컴파일하는 것)이 불가능하다고 가정하고 프로그램이 작동하는 방식을 조정하는 데 사용하는 것입니다 . 또 다른 옵션은예상대로 실행되도록 C 바이너리 패치.
답변2
read
계속하기 전에 이를 사용하여 사용자 입력을 기다릴 수 있습니다.
예:
프로그램은 루프를 실행하고 출력을 인쇄하고 ls -lhtr
사용자 입력(Enter 또는 다른 문자 누르기)을 기다린 다음 출력을 다시 인쇄하고 무한 루프에서 프로세스를 계속합니다.
#!/bin/bash
while (true); do
ls -lhtr;
read i;
done
따라서 기본적으로 ls -lhtr
모니터링해야 하는 출력이 있는 명령을 사용할 수 있으며 환경과 파일을 수정한 후에는 아무 키나 다시 눌러 명령 출력을 계속 모니터링할 수 있습니다.