以下是perl中的这一行:
open my $fh_echo, '-|' or exec "$sshstr \"$str\"";
基本上它是exec的$ sshstr然后输出进入$ fh_echo,不知何故。我很好奇这个操作背后的机制。有人可以解释一下' - |'装置
此外,如何将输出加载到$ fh_echo?它是一点一点输出还是$ fh_echo只是exec输出的句柄?
哈哈,我甚至不能谷歌这个因为 - |不要出现在结果中。答案 0 :(得分:4)
见perlfork。这是一个分叉管道。
基本上,|-
管道输出到分叉子进程,-|
从父进程读取(在子进程内)。
如果在命令' - '上打开管道,即'| - '或' - |'使用open()的2参数(或1参数)形式,然后有一个隐式fork完成,并且 open的返回值是父进程中子进程的pid,子进程内为0。
在您的示例中,您打开一个管道来读取子进程,然后分叉,然后在子进程中用$sshstr
替换进程。
答案 1 :(得分:2)
这似乎与open my $fh_echo, "-|", "$sshstr \"$str\""
完全相同。它贬低为:
exec qq[$sexec qq[$sshstr "$str"] unless open my $fh_echo, '-|'
当事情成功打开时,输出并没有真正加载到$ fh_echo中,$ fh_echo变成了一个文件句柄,通过管道在open()的最右边的参数中输出可执行文件。有关管道的更多信息,请查看wikipedia page。应该指出的是,你给出的例子并没有打开任何东西。因为在您提供的示例的右侧没有命令,open()将始终返回指示失败的非true值,并且表达式的右侧将始终运行。见http://ideone.com/wupJ8
如果要获得更多成功,我们将使用open my $f, "-|", "echo hi"
作为更好的示例。这样做是重新定义stdin,因为子进程是管道的右侧,使其大致相当于以下内容:
pipe my $fh_echo, my $childout;
if (fork == 0) {
close STDOUT;
open STDOUT, ">>&", $childout;
exec "echo hi";
}
首先创建一个管道,然后分叉。在子进程中,stdout被重新定义为管道的写入端。然后调用exec
(有关更多详细信息,请参阅exec(2)),它将当前进程替换为给定进程。从那时起,由于stdout已被重新定义为管道的可写端,因此stdout的所有输出实际上都将写入管道,而不是目标可能曾经存在的那些。
另外,要进一步详细说明exec“echo hi”缺陷到shell,因为它不是完全限定的可执行路径。也就是说,它实际上被perl读为exec "/bin/sh", "echo hi"
,因为perl决定不做出给定表达式可能意味着什么的决定。
希望这能解释机制。