PERLでのシステムコールの標準出力ファイルハンドルを変更するにはどうすればよいですか?
質問
Selectを使用して、システム関数のSTDOUTを変更しようとしています。しかし、それは機能していないようです。システム出力は、ファイルにリダイレクトされるのではなく、コンソールに表示されています。
use strict;
use warnings;
chdir "C:\\Documents and Settings\\" or die "cannot open the dir\n";
open FH, ">out.txt" or die "cannot open out.txt\n";
select FH or die " cannot change the stdout\n";
system "dir /a" ;
私にできるが system "dir /a > out.txt"
, 、上記のコードが機能していない理由を知りたいです。
解決
select
関数は、出力のデフォルトのファイルハンドルを変更します。 STDOUTは変更されません。これは、出力のデフォルトのファイルハンドルであるかどうかに関係なく、それが指すものを指すものを指します。 stdoutを変更したい場合は、YlebreやJonの答えのようなことをしなければなりません。
子プロセスを開始すると、親と同じ標準出力が得られます。親のデフォルトのファイルハンドルが何であるかは気にしません。
他のヒント
コードの問題はそれです system
コマンドは出力をキャプチャしません。使用できます qx//
:
use strict;
use warnings;
open my $fh, ">", "output.txt" or die $!;
my $oldfh= select $fh;
print qx/ls -a/;
select $oldfh;
close $fh or warn $!;
外部アプリケーションを実行して取得する他のオプションがあります。 IPC::Open2
と IPC::Open3
モジュール。デフォルトではPerlに含まれています。
サイドノート:ファイルハンドルにグローブを使用しないでください:それらはグローバルであり、グローバルは悪です。代わりに語彙変数を使用します(FH
vs。 $fh
)。また、3つの引数を使用する必要があります open
前者は後者よりも安全であるため、2つのパラメーターの代わりに。
多分 これ 役立ちます
この場合、「選択」があなたが探しているものであるかどうかはわかりません。 stdoutをファイルにリダイレクトするには、次のことを行うことができます。
use strict;
use warnings;
use IO::Handle;
open FH, "> out.txt";
STDOUT->fdopen( \*FH, 'w' ) or die $!;
print "Hello world!\n";
system "dir /a";
お役に立てれば!
システム(Perlではなく)レベルでファイル記述子を再割り当てします。
sub reopen($$$) {
open $_[0], $_[1]. '&='. fileno($_[2]) or die "failed to reopen: $!";
}
reopen *STDOUT, '>', $new_stdout_handle;
これで、あなたがフォークするものはすべて、$ new_stdout_handleが標準出力であると考えるでしょう。
私は要点に完全な例を貼り付けました: http://gist.github.com/129407