Shell 更改Perl 6';s$*是否更改了子进程的标准输出?
我正在玩Shell 更改Perl 6';s$*是否更改了子进程的标准输出?,shell,stdout,raku,Shell,Stdout,Raku,我正在玩shell,以及在调用程序中更改标准文件句柄时它的行为。说: $in、$out和$err是要启动程序的三个标准流,默认为“-”,这意味着它们从父进程继承流 据我所知,外部程序不使用相同的文件句柄: #!/Applications/Rakudo/bin/perl6 #`( make an external Perl 6 program the outputs to standard handles ) my $p6-name = 'in-out.p6'.IO; #END
shell
,以及在调用程序中更改标准文件句柄时它的行为。说:
$in、$out和$err是要启动程序的三个标准流,默认为“-”,这意味着它们从父进程继承流
据我所知,外部程序不使用相同的文件句柄:
#!/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";
输出显示,当我打开/dev/null并将其文件句柄分配给$*OUT
时,当前程序的输出不会显示在终端中(没有以3.
开头的输出)。但是,当我调用shell
时,其标准输出变为原始标准输出:
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
我不担心如何做到这一点。我可以创建一个Proc
对象并将文件句柄传递给它
是否还有其他问题?默认情况下,
$*OUT
中的IO::句柄绑定到操作系统提供的低级标准输出文件句柄
shell
和run
只要让生成的进程使用提供给Perl 6的低级标准输出文件,除非您另有指定
Perl 6在生成新进程之前不会改变任何外部环境
最简单的方法是将要使用的filehandle对象指定给带有命名参数的
shell
或run
调用
#没有失败测试,因为默认情况下无论如何都会抛出错误
我的$p6 name='in out.p6'.IO;
结束$p6-name.unlink;
$p6 name.sprut(Q'put“STDOUT:@*ARGS[0]”;注意“STDERR:@*ARGS[0]”);
运行$*可执行文件,$p6 name,'run',:out(打开'/dev/null',:w);
{
temp$*OUT=open'/dev/null',:w;
shell“$*可执行文件“$p6名称”“shell”“”:err($*OUT);
}
这导致
STDERR:运行
标度:贝壳
在丢弃输出数据的特殊情况下,:!退出
或:!应改用err
run$*可执行文件,$p6名称,'no STDERR',:!犯错误
STDOUT:没有STDERR
如果您只想为自己截取数据,请执行以下操作:
my$fh=run($*可执行文件,$p6名称,'capture',:out);
打印“捕获:”,$fh.slurp-rest;
captured:STDOUT捕获
MoarVM中的相关代码似乎在。在Windows上,第一次运行脚本时,它找不到刚刚创建的文件。在第二次运行时,我观察到了相同的行为(将/dev/null
替换为NUL
)。文档中是否有讨论“基本上修改Perl 6中除%*ENV之外的任何变量都不会产生任何外部影响”的地方?这是一个设计目标还是一个实现问题?