web-dev-qa-db-ja.com

すでに実行されているプロセスからstdoutをキャプチャするにはどうすればよいですか?

しばらくの間実行されるcronジョブがあり、その標準出力を表示したいと思います。プロセスがcronによって開始されたという事実がどれほど重要かはわかりませんが、言及したいと思います。これはOSX上にあるので、.../proc/[pid]/...、truss、straceなどにアクセスできません。 IOリダイレクトで実行することの提案(例:script > output & tail -f output)このプロセスは1)すでに実行されており、2)リダイレクトで停止/再起動できないため、受け入れられません。さまざまなUnicesで機能する一般的なソリューションがある場合、それは理想的ですが、具体的には、現在Macでこれを実現しようとしています。

25
theraccoonbear

OSXの真のソリューション

~/.bashrcまたは~/.zshrcに次の関数を記述します。

capture() {
    Sudo dtrace -p "$1" -qn '
        syscall::write*:entry
        /pid == $target && arg0 == 1/ {
            printf("%s", copyinstr(arg1, arg2));
        }
    '
}

使用法:

example@localhost:~$ Perl -e 'STDOUT->autoflush; while (1) { print "Hello\n"; sleep 1; }' >/dev/null &
[1] 97755
example@localhost:~$ capture 97755
Hello
Hello
Hello
Hello
...

https://github.com/mivok/squirrelpouch/wiki/dtrace

注:

ElCapitan以降ではdtrace制限を無効にする必要があります。

csrutil enable --without dtrace
42
mpyw

免責事項:Macにこれがあるかどうかはわかりません。この手法はLinuxに存在します。 YMMV。

/ procからstdout/errを取得できます(適切な特権を前提としています)。

PID=$(pidof my_process)
tail -f /proc/$PID/fd/1

または、バッファに残っているすべてのものをファイルに取得します。

cat /proc/$PID/fd/1

PS:fd/1はstdout、fd/2はstderrです。


編集:アレックスブラウン> Macにはこれがありませんが、Linuxにとっては便利なヒントです。

20
Mark Renouf

使用する dtruss -p <PID>、 あるいは rwsnoop -p <PID>

6
Alex Brown

neercs は、外部で開始されたプログラムを「取得」する機能があります。おそらくそれはあなたのために働くでしょう。ところで、トラスやstraceはありませんが、dtraceはあります。

1
LaC

あなたがcronで始めたという事実はあなたを救うことができると思います。 Linuxでは、cronジョブの標準出力は、ジョブを所有するユーザーのunixメールアカウントにメールで送信されます。ただし、OSXについてはよくわかりません。残念ながら、メールが送信される前にジョブが終了するのを待つ必要があり、出力を表示できます。

0
Sodved