他のコマンドの出力と指定された文字列が印刷されたときを監視するツールが必要です。監視対象のコマンドを停止するには「エラー」が発生します。その後、一部の環境とファイルを変更して作業を続けます。可能ですか?
編集:はい:
次の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
もう1つのアイデアは、最も賢明なオプション(ソースからプログラムを再コンパイルすること)が不可能であると仮定し、プログラムの動作方法を調整するために使用することです。別のオプションは期待どおりに実行する C バイナリパッチ。
答え2
read
続行する前に、これを使用してユーザー入力を待つことができます。
例:
プログラムはループを実行し、出力を印刷してls -lhtr
ユーザー入力(Enterまたは他の文字を押す)を待ってから、出力を再印刷して無限ループでプロセスを続行します。
#!/bin/bash
while (true); do
ls -lhtr;
read i;
done
したがって、デフォルトでls -lhtr
監視する必要がある出力を持つコマンドを使用できます。環境とファイルを変更したら、任意のキーをもう一度押してコマンド出力を監視し続けることができます。