PERLでのシステムコールの標準出力ファイルハンドルを変更するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/990913

  •  13-09-2019
  •  | 
  •  

質問

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::Open2IPC::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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top