
ローカルで作業している間は、リモートコンピュータで実行されるスクリプトが残ります。同じユーザーとしてSSH経由でコンピュータに接続しますps
。
$ ps aux | grep ipcheck
myuser 18386 0.0 0.0 18460 3476 pts/0 S+ Dec14 1:11 /bin/bash ./ipchecker.sh
ローカルセッションからstdoutとして印刷します(./ipchecker.sh
ローカルターミナルウィンドウで実行されており、リダイレクトなし、使用なしscreen
など)。
とにかく、SSHセッション内で(停止せずに)この実行コマンドの出力を表示できますか?
これまで私が見つけた最良の方法はを使用することです。strace -p 18386
しかし、画面を横切って飛び回る数多くのテキストが表示され、あまりにも詳細です。出力を停止しstrace
てからフィルタリングしてstdoutに印刷されたテキストを見つけることができますが、非常に長くて混乱し、停止すると明らかに何かを見逃す可能性があります。まるでローカルで作業しているかのように、リアルタイムでスクリプト出力を表示する方法を見つけたいと思います。
誰でもこれを改善できますか?確実な答えは、セッションなどでスクリプトをリダイレクトまたは再起動することですscreen
。これは仕事にとって重要なスクリプトではないので、そうすることができます。むしろ面白い学習運動だと思いました。
答え1
ファイルシステムを介して出力にアクセスできますproc
。
tail -f /proc/<pid>/fd/1
1
=標準出力、2
=標準エラー
(または@jmhostaletが言ったように:cat /proc/<pid>/fd/1
tailが機能しない場合)
答え2
既存のプロセスのみを監視したい場合は、strace -p1234 -s9999 -e write
プロセスIDが1234の場所を使用できます。 (-s9999
文字列を32文字に切り捨てたり、出力を生成したりするシステムコールを避けてください。)特定のwrite
ファイルディスクリプタに書き込まれたデータのみを表示するには、strace -p1234 -e trace= -e write=3
ファイルディスクリプタ3に書き込まれたデータのみを表示などのものを使用できます。-e trace=
システムコールが記録されます。)これにより、すでに生成された出力は提供されません。
出力が速すぎるまでスクロールすると、ポケットベルにパイプするか(たとえば)を使用してless
ページに送信できますstrace -o trace.log …
。
多くのプログラムでは、ptrace ハッキングを使用して、後続の出力を現在の端末または新しい画面セッションに転送できます。バラより実行中のプロセスを拒否し、それを新しいスクリーンシェルに接続する方法は?そして他のリンクされたスレッド。
システムの設定方法によっては、strace
プロセスが追加の権限なしでユーザーとして実行されている場合でも、これらのコマンドをすべてrootとして実行する必要があります。 (プロセスが別のユーザーとして実行されているか、setuidまたはsetgidの場合は、rootとしてstrace
実行する必要があります。)ほとんどのディストリビューションでは、プロセスがサブアイテムを追跡することを許可します。(これはいくつかのセキュリティ上の利点を提供します。つまり、いくつかの直接的なマルウェアの注入を防ぎますが、ファイルの変更による間接的な注入を防ぎます。)これはkernel.yama.ptrace_scome
sysctlによって制御されます。
答え3
BSDでは、次のものを使用できます。watch
与えられたttyを受け取ります。
watch /dev/pts/0
screen
Linuxでは、以前またはマルチプレクサでプロセスが実行されていない場合、これは不可能ですtmux
。また見なさい:Reptyr:実行中のプロセスを新しい端末に接続する
唯一の方法は、プロセスをデバッグすることです(例:strace
/、dtrace
dtruss
gdb
、、lldb
など。 )。
を使用したため、意味のある出力を取得するには、限定式(例)でフィルタリングしてから出力を解析する必要がありますstrace
。file
例は次のとおりです。
strace -e trace=write -s1000 -fp 18386 2>&1 | grep -o '".\+[^"]"'
これは、PID(長さ1000)で指定されたプロセスの書き込み操作を印刷し(pgrep
名前で照会用)、標準エラーを出力にリダイレクトし(フィルター用)、二重引用符で囲まれた文字列を印刷することです。
バイナリ出力を処理する場合は、read
(with -r
)とprintf
(with %b
)を使用してエスケープシーケンス文字を解析できます。
while read -r -t1 line; do printf "%b" $line; done
より多くのパラメータを確認してくださいhelp read
(-n
改行ではなく特定の文字数の後に印刷するなど)。
以下はより完全な例です。
strace -e trace=write -s1000 -fp 18386 2>&1 \
| grep --line-buffered -o '".\+[^"]"' \
| grep --line-buffered -o '[^"]\+[^"]' \
| while read -r line; do
printf "%b" $line;
done
プロセスを使用する例については、以下を確認してください。シェルでstraceをプレーンテキストに解析する方法は?スタックオーバーフロー時
答え4
stderrとstdoutを取得するには、次のように実行できます。
tail -f /proc/<pid>/fd/*