Monitoring

輸出一些字元串時如何暫停命令?

  • July 13, 2018

我需要一個工具來監視其他命令的輸出,以及何時列印指定的字元串,例如。“錯誤”,停止監控的命令。然後我修改一些環境和文件並繼續工作。是否可以?

編輯:範例:

有以下job.sh

for i in $(ls)
do
   echo file $i
   sleep 0.1
   cat $i
done

在包含文件 a.txt 和 b.txt 的文件夾中執行時,我想在列印後暫停 job.sh 以file b.txt進行編輯,然後繼續 job.sh 並查看新的 b.txt 內容。我不能觸摸 job.sh 因為它實際上是編譯的 C 程序。睡眠象徵著暫停不必立即,但仍然很快。

% ./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;
}

通過在調試器下執行 AC 程序可以更好地控制它,例如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, 和呼叫 sosleep

% 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 二進製文件以使其按需要執行

引用自:https://unix.stackexchange.com/questions/455076