2017-12-18 15 views
1

私はlog.txtというの内側に印刷する必要がある「内部」の文字列を必要とし、perlスクリプトの下いくつかのコマンドの出力をファイルにリダイレクトするが、いくつかのコマンドをコンソールに残す方法はありますか?

open (STDOUT, '>',"log.txt")|| die "ERROR: opening log.txt\n"; 
print "\n inside"; 
close (STDOUT); 
print "\noutside"; 

を使用しています。文字列「外側」をコンソールに印刷する必要があります。

しかし、log.txtというの内側に印刷されていますが、「外」の文字列がコンソールに印刷されていません。「内部」私のスクリプト文字列と

誰もがopen STDOUT, '>', $fileのファイルにこの

+0

'使用の警告を追加し、あなたのコードに'、あなたは、警告メッセージが表示されます。 – toolic

+0

ようこそStackoverflowへ。参照してください。[誰かが私の質問に答えるとき、私は何をすべき?](http://stackoverflow.com/help/someone-answers)そして、周りの[ヘルプページ](https://stackoverflow.com/help)を見て、短期であります明らかである。投稿された回答について質問がある場合、それは話すことが予想され、人々は通常、反応して物事を明確にします。 – zdim

答えて

2

あなたredirect the standard output streamで私を助けることができます。その後、コンソールに簡単に印刷する方法はありません。

リダイレクトする前に、ファイルとコンソール

  • 保存STDOUTの両方に印刷し、必要なときに、後でそれを復元するにはいくつかの方法が。ここでも、あなたがコンソールを意図するもの変数に印刷open

    open SAVEOUT, ">&STDOUT" or warn "Can't dup STDOUT: $!"; 
    open *STDOUT, ">", $logfile or warn "Can't redirect STDOUT to $logfile: $!"; 
    say "goes to file"; 
    ... 
    open STDOUT, ">&SAVEOUT" or warn "Can't reopen STDOUT: $!"; # restore 
    say "goes to console"; 
    
  • を参照してください。そうでなければ、一度selectバックSTDOUT

  • を印刷するすべてのSTDOUT-意図プリントを出すだろう、プリントはあなたがSTDOUTを指定することで、コンソールに到達することができますこれにより

    open my $fh_so, '>', \my $for_stdout; 
    select $fh_so; 
    say "goes to variable \$for_stdout"; 
    say STDOUT "goes to console"; 
    ... 
    select STDOUT; # make STDOUT default again 
    say $for_stdout; # goes to console (all accumulated $fh_so prints) 
    

    をどこに行くのデフォルトを切り替えるためにselectを使用Jens's answer

    open my $fh_log, '>', $logfile or die "Can't open $logfile: $!"; 
    say $fh_log "goes to $logfile"; 
    say   "goes to console"; 
    ... 
    close $fh_log; 
    

    デフォルトprint(というかのように直接ファイルへのログ、上の210)はコンソールに移動し続けます

最初の2つは少し面倒ですが、そうではありません。私はSTDOUTは、プログラムのほとんどのためにリダイレクトする必要がない限り、ログファイルにログを直接印刷することをお勧めしたい、またはあなたの周りselectファイルハンドルへの説得力のある理由があります。

の場合、改行が印刷される部分に追加されるため、最初にuse feature 'say';が必要です。

常にuse warnings;use strict;を使用してプログラムを起動します。

+0

ありがとう、私はあなたがSTDOUTをリダイレクトすることができるとは知らなかった。それは技術的にはあなたがまだこの上の背景のための標準的なドキュメントの – beasy

+1

@beasy一つですが、コンソールに印刷する 'warn'を使用することができることを私を打つ[I/Oリダイレクション(bashの)](http://tldp.org/LDP /abs/html/io-redirection.html)。しかし、モジュールがそれをはるかに簡単にすることに注意してください。たとえば、私は[this post](https://stackoverflow.com/a/47045913/4653379)と[this post](https:// stackoverflow。com/a/43501427/4653379) – zdim

+0

@beasy実際、警告は異なるストリーム(fd 2)であるSTDERRに送られます。そのストリームは、リダイレクトされない限り、コンソール上に出ます。 STDOUTがプログラムのためにリダイレクトされると、通常はSTDERR(まったく同じ方法で)と通常は別のファイルにリダイレクトされます。これは、そのようなプログラムがcronや他のツールから無人で実行されるためであり、すべての出力がファイルで必要になるからです。その後、プログラムはSTDERRファイルがemtpyであるかどうかを最終的にチェックすることができ、そうでなければ私に電子メールを送信してエラーがあることを警告します(それ以外の場合はファイルを削除します)。 – zdim

関連する問題