3

シェルでコマンドを実行し、その出力を解析する Perl スクリプトを作成しています。シェルとして、csh を使用するつもりです。私はこれで始めました

my $out = `cmd`

しかし、それは私も必要とするSTDERRをキャプチャしません。出力リダイレクトを指定して sh を実行しても何も起こらない

my $out = `sh -c "cmd 2>&1"`

STDERR ではなく、STDOUT のみをキャプチャします。

csh のファイルにリダイレクトしても機能しません

tcsh$ cmd >& logfile.log

まだ STDOUT のみをキャプチャします %)

実行しようとしているコマンドは実際には sh スクリプトであり、このスクリプトの一部のコマンドは STDERR に出力され、その出力をキャプチャしたいと考えています。STDERRを実行すると、sh -c "cmd 2>/dev/null"実際には /dev/null に移動し、STDOUT のみが端末に出力されます。

誰でもこれで私を助けることができますか?

4

5 に答える 5

2

あなたが私たちに伝えていないことがあると思います。あなたはcygwinを使っていますか?それともWindows?PERL5SHELL環境変数を設定していますか?

これらは両方とも、私が簡単にテストできる5つのプラットフォームで正常に動作するため、あなたが私たちに言っていないことがあります。

% perl -le '$out = `sh -c "grep missing /dev/nowhere 2>&1" | cat -n`; chomp $out; print "got <<<$out>>>"'
got <<<     1   grep: /dev/nowhere: No such file or directory>>>

しかし、これまでのところ、シェルアウトのために明示的にsh (1)を呼び出す理由はありません。これは、Perlがすべてのバックティック、パイプのオープン、およびシェルアウトに対して常にsh (1) を呼び出すためです。system()

% perl -le '$out = `grep missing /dev/nowhere 2>&1 | cat -n`; chomp $out; print "got <<<$out>>>"'
got <<<     1   grep: /dev/nowhere: No such file or directory>>>

私が考えることができる唯一の例外は、Unix 以外のシステムで発生します。これらのシステムには/bin/shがないため、別の何かが定義されています。

しかし、単純なシェルアウトが背後でtcsh (1) を呼び出すことは決してありません。それを実現するには、 perl (1) ソースを真剣にハックする必要があったでしょう。"/bin/tcsh"また、文字列が よりも長くなり、とにかく/bin/"/bin/sh"で見つかることはあまりないため、バイナリを (簡単に) ハッキングできるとは思えません。

シェルからでも stderr リダイレクトが機能しないということは、かなり奇妙なことが起こっていることを示しています。もっと情報が必要だと思います。

于 2011-04-21T03:16:24.103 に答える
1

shここでは、のSTDERRではないのSTDOUTをキャプチャしていますcmd

my $out = `sh -c "cmd 2>&1"`;

直接走れcmdますか?

my $out = `cmd 2>&1`;
于 2011-04-19T09:02:15.500 に答える
1

いつものようにサンプルをモックアップする時間も、テストする時間もありません。それが役立つかどうかを確認するために使用Capture::Tinyしてみてもよいと思います。

于 2011-07-24T15:49:56.737 に答える
1

tcshでコマンドを実行するとcmd >& logfile.log、stderr ではなく、cmd の stdout のみがログ ファイルに送信されるとのことでした。それは意味がありません。

cmd を次のスクリプトに置き換えてみてください。

#!/bin/sh

echo stdout
echo STDERR 1>&2

「stdout」と「STDERR」の両方が logfile.log に表示されるはずです。

もしそうなら、おそらくあなたの「cmd」は何か奇妙なことをしています。私の推測では、cmd は stdout や stderr ではなく、/dev/tty に書き込みを行っていると思われます。リダイレクトの影響を受けません。

意味を理解するには、上記のスクリプトに次の行を追加します。

echo tty > /dev/tty
于 2011-07-23T21:55:27.647 に答える
1
  • 逆引用符は、STDERR ではなく STDOUT をキャプチャします。
  • systemstdout と stderr の両方を親の設定にダンプします。
  • STDERR をキャプチャする場合は、次のようなものが必要ですIPC::Open3

open2()と非常に似ており、open3()は指定された $cmd を生成し、CHLD_OUT を子からの読み取り用に、CHLD_IN を子への書き込み用に、CHLD_ERR をエラー用に接続します。CHLD_ERR が false の場合、

于 2011-04-19T12:14:56.840 に答える