كيف يمكنني تغيير ملفات الإخراج القياسية لاستدعاء النظام في بيرل؟

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

  •  13-09-2019
  •  | 
  •  

سؤال

أحاول تغيير 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 تعمل الدالة تغييرات Filehandle الافتراضية للإخراج. لا يغير الأمر Stdout، والذي يشير إلى ما يشير إليه بغض النظر عما إذا كان Filehandle الافتراضي للإخراج. إذا كنت ترغب في تغيير Stdout، عليك أن تفعل شيئا مثل إجابة ylebre أو Jon.

عند بدء تشغيل عملية تابعة، يحصل على نفس الإخراج القياسي مثل الوالد. لا يهتم بما هو الافتراضي Filehandle من الوالد هو رغم ذلك.

نصائح أخرى

المشكلة مع الكود الخاص بك هو ذلك 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 وحدات. يتم تضمينها في بيرل افتراضيا.

ملاحظة جانبية: لا تستخدم Globs مقابض الملفات: إنها Globals، والكبراءات شريرة. استخدام المتغيرات المعجمية بدلا من ذلك (FH ضد. $fh). أيضا، يجب عليك استخدام الحجة الثلاثة open بدلا من معلمين، لأن السابق أكثر أمانا من الأخير.

يمكن هذه تساعد

لست متأكدا من "الاختيار" هو ما تبحث عنه في هذه الحالة. لإعادة توجيه 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";

أتمنى أن يساعدك هذا!

أعمد واصفات الملف على مستوى النظام (وليس بيرل):

    sub reopen($$$) {
        open $_[0], $_[1]. '&='. fileno($_[2]) or die "failed to reopen: $!";
    }

    reopen *STDOUT,  '>', $new_stdout_handle;

الآن أي شيء سيعتقد أن $ new_stdout_handle هو الإخراج القياسي.

لقد قمت بلصق مثال كامل على GIST: http://gist.github.com/129407.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top