gpt4 book ai didi

shell - 更改 Perl 6 的 $*OUT 是否会更改子进程的标准输出?

转载 作者:行者123 更新时间:2023-12-04 02:18:28 25 4
gpt4 key购买 nike

我在玩shell以及当我更改调用程序中的标准文件句柄时它的作用。 Proc说:

$in, $out and $err are the three standard streams of the to-be-launched program, and default to "-", which means they inherit the stream from the parent process.



据我所知,外部程序不使用相同的文件句柄:
#!/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::Handle绑定(bind)到操作系统给定的低级 STDOUT 文件句柄。
shellrun除非您另外指定,否则只需让生成的进程使用提供给 Perl 6 的低级 STDOUT 文件。

Perl 6 在产生新进程之前不会改变任何关于外部环境的内容。

最简单的做法是将要使用的文件句柄对象提供给 shellrun使用命名参数调用。

# 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);
}

这导致

STDERR: run
STDOUT: shell

在丢弃输出数据的特殊情况下, :!out:!err应改为使用。

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

STDOUT: no STDERR

如果你只想为你截取数据 :out:err这样做;

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

captured: STDOUT capture

关于shell - 更改 Perl 6 的 $*OUT 是否会更改子进程的标准输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42505139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com