練習問題2 (14章 プロセス管理

問題1のプログラムを改造して、コマンドの出力をカレントディレクトリのls.outというファイルに書き出すようにしてください。また、エラー出力は、ls.errというファイルに出力してください。
初めてのPerl P.249

これもよくわからなかった問題。
間違っていますが、自作コードは以下になります。

#!/usr/bin/perl

use strict;
use warnings;

my $out_file = 'ls.out';
open(STDOUT, > $out_file) or die "$out_fileを出力用にオープンできませんでした\n";

my $err_file = 'ls.err';
open(STDERR, > $err_file) or die "$err_fileをエラー出力用にオープンできませんでした\n";
select STDERR;

chdir "/" or die STDOUT "ルートディレクトリに移動できませんでした\n";
open(PROC, 'dir|') or die STDOUT "dirプロセスをオープンできませんでした\n";
while(<PROC>) {
    print STDOUT "$_";
}

標準出力、エラーをどうやって使い分けるのかが全くもってわかりませんでしたが、筋は間違っていませんでした。


一番の間違いは、
「標準入力、出力、エラーなどの標準ファイルハンドルを再オープンした時は、明示的に出力先を指定しなくても良い」
というところですね。
自身が定義したファイルハンドルとの違いをハッキリさせておくことが大事ですね。

そうなると、上記のコードの

select STDERR;

という箇所は消去して、

chdir "/" or die STDOUT "ルートディレクトリに移動できませんでした\n";

このような箇所は

chdir "/" or die"ルートディレクトリに移動できませんでした\n";

上記のようにするだけで機能しますね。


あとは微調整として

open(STDOUT, > $out_file)

ここの
'> $out_file'をダブルクォートで囲むだけですね。

そんなわけで
修正後のコードは以下のようになりました。

#!/usr/bin/perl

use strict;
use warnings;

my $out_file = 'ls.out';
open(STDOUT, "> $out_file") or die "$out_fileを出力用にオープンできませんでした\n";

my $err_file = 'ls.err';
open(STDERR, "> $err_file") or die "$err_fileをエラー出力用にオープンできませんでした\n";

chdir "/" or die "ルートディレクトリに移動できませんでした\n";
open(PROC, 'dir|') or die "dirプロセスをオープンできませんでした\n";
while(<PROC>) {
    print "$_";
}

出力結果は、
ls.outファイルは

#AUTOEXEC.BAT# Perl
#ChangeLog# Program\ Files
#del.pl# RECYCLER
.....
.....
.....

上記のようになり、
ls.errファイルは空になりました。

OKですね。