2017-02-28 70 views
9

shell ile oynamaktayım ve çağıran programdaki standart dosya kümelerini değiştirdiğimde nasıl davranıyor. Proc diyor ki:

$ içeri, dışarı, $ ve err to-açılacak programın üç standart akışları vardır $ ve varsayılan için "-", onlar üst sürecinden akışı devralan anlamına gelir.

Bildiğim kadarıyla söyleyebilirim, aynı dosyayı kullanmaz dış program kolları :

#!/Applications/Rakudo/bin/perl6 

#`(
    make an external Perl 6 program the outputs to standard handles 
    ) 
my $p6-name = 'in-out.p6'.IO; 
#END try $p6-name.unlink; # why does this cause it to fail? 
my $p6-fh = open $p6-name, :w; 
die "Could not open $p6-name" unless ?$p6-fh; 
$p6-fh.put: Q:to/END/; 
    #!/Applications/Rakudo/bin/perl6 

    $*ERR.say(qq/\t$*PROGRAM: This goes to standard error/); 
    $*OUT.say(qq/\t$*PROGRAM: This goes to standard output/); 
    END 
$p6-fh.close; 
say $p6-name.e ?? 'File is there' !! 'File is not there'; 
die "$p6-name does not exist" unless $p6-name.e; 

{ 
#`(
    Start with some messages to show that we can output to 
    the standard filehandles. 
    ) 
$*OUT.put: "1. standard output before doing anything weird"; 
$*ERR.put: "2. standard error before doing anything weird"; 
shell("perl6 $p6-name").so; 
} 

{ 
#`(
    This block assigns a new filehandle to $*OUT and prints a 
    message to it. I expect that message to not show up in the 
    terminal. 

    It then calls run-them to fire off the external process. It 
    should inherit the same standard out and its standard out 
    messages should not show up. But, they do. 
    ) 
temp $*OUT = open '/dev/null', :w; 
$*OUT.put: "3. temp redefine standard output before this message"; 
shell("perl6 $p6-name").so; 
} 

$*OUT.put: "4. everything should be back to normal"; 

çıkış gösteriyor ki ben /dev/null açıp onun dosya tanıtıcısından atadığınızda $*OUT, mevcut programın çıkış terminalinde görünmüyor (3. ile başlayan çıkış yok). Ben shell çağrı Ancak, standart çıkış orijinal standart çıkışa gider:

File is there 
1. standard output before doing anything weird 
2. standard error before doing anything weird 
    in-out.p6: This goes to standard error 
    in-out.p6: This goes to standard output 
    in-out.p6: This goes to standard error 
    in-out.p6: This goes to standard output 
4. everything should be back to normal 

Bunun gerçekleşmesi için nasıl endişelenmiyorum. Bir Proc nesnesi oluşturabilir ve dosya dosyalarını ona geçirebilirim.

Başka bir şey var mı?

+1

MoarVM ilgili kodu (https://github.com/MoarVM/MoarVM/blob/7bd72321b0f009178c1931d50c8faae6bf4a25d8/src/io/procops.c#L184) [MVM_proc_shell] gibi görünüyor. Windows'da, komut dosyasının çalıştırıldığı ilk seferde, oluşturduğu dosyayı bulamıyor.İkinci çalışmada, aynı davranışı gözlemliyorum ('/ dev/null' yerine' NUL' ile değiştirdikten sonra). –

cevap

4

Varsayılan olarak IO $*OUT işletim sistemi tarafından verilen düşük seviyeli STDOUT dosya tanıtıcısına bağlandığı içinde olmasıdır Kulp ::.

shell ve run yalnızca, aksi belirtilmedikçe, perleli işlemin Perl 6'ya verilen düşük düzey STDOUT dosyasını kullanmasına izin verin.

Perl 6, dış ortam hakkında yeni bir süreç ortaya çıkana kadar bir şey değiştirmez.


yapılacak en basit şey adlandırılmış bağımsız değişkenle shell veya run çağrı için kullanmak istediğiniz dt nesneyi vermektir. çıktı verilerini atmadan özel durumda

STDERR: run 
STDOUT: shell 

içinde

# no testing for failure because the default is to throw an error anyway 

my $p6-name = 'in-out.p6'.IO; 
END $p6-name.unlink; 

$p6-name.spurt(Q'put "STDOUT: @*ARGS[0]";note "STDERR: @*ARGS[0]"'); 

run $*EXECUTABLE, $p6-name, 'run', :out(open '/dev/null', :w); 

{ 
    temp $*OUT = open '/dev/null', :w; 
    shell "'$*EXECUTABLE' '$p6-name' 'shell'", :err($*OUT); 
} 

Bu sonuçlar, :!out veya :!err yerine kullanılmalıdır.

run $*EXECUTABLE, $p6-name, 'no STDERR', :!err; 
STDOUT: no STDERR 

sadece verileri :out için ele geçirilmesi ve :err sadece bunu istiyorum;

my $fh = run($*EXECUTABLE, $p6-name, 'capture', :out).out; 
print 'captured: ',$fh.slurp-rest; 
captured: STDOUT capture 
+3

Tamam, ancak Proc dokümanlar kabukun ana işlem akışlarını miras aldığını söylüyor. Dokümanlar içinde "Perl 6'da% * ENV dışında herhangi bir değişkeni temelde değiştirmenin dış etkiye sahip olmadığını" tartışan bir yer var mı? Bu bir tasarım hedefi mi yoksa uygulama sorunları mı? –