巴什像PIPESTATUS相当于perl的 [英] Bash like PIPESTATUS equivalent for perl

查看:341
本文介绍了巴什像PIPESTATUS相当于perl的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是捕获perl的外部发出命令的退出code。诀窍是,外部命令实际上是由在那里的第一个命令是通过管道输送到第二个命令两个命令。对于我而言,我需要第一个命令的退出code。 Bash使用为此几个可能方式如

My goal is to capture the exit code of external command issued from perl. The trick is that the external command is actually composed of two commands where first command is piped to second command. For my purposes I need exit code of first command. Bash uses for this purpose several possible ways e.g.

$ false | true; echo "${PIPESTATUS[0]}"
1
$ true | false; echo "${PIPESTATUS[0]}"
0

阅读这个问题后,我发现,perl的系统命令能够获取进程退出code,所以我已经试过以下内容:

After reading about this problematic I've found that perl system command is able to get exit code of process so I've tried following:

$ exit 10 | true
$ echo ${PIPESTATUS[0]}
10
$ true | false
$ echo $?
1
$ perl -e 'my $code = system("true | false"); print $code . "\n"'
256
$ perl -e 'my $code = system("bash -c \"true | false\""); print $code . "\n"'
256
$ perl -e 'my $code = system("bash -c \"exit 2\""); print $code . "\n"'
512
$ perl -e 'my $code = system("bash 2>&1 >/dev/null"); print $code . "\n"'
$ exit 10
exit
2560

正如你可以看到我从系统命令越来越怪异回报codeS(256,512,2560)。我认为这是关系到我的另一个<一个href=\"http://stackoverflow.com/questions/28413580/perl-what-is-the-return-value-of-perl-system-function\">question.到目前为止,我能够访问第一个命令返回code中的唯一可能的方式是使用 QW 或backtickss``。这似乎为AA有点矫枉过正了我,因为我需要回声来捕捉 PIPESTATUS [0] 值。

As you can see I am getting weird return codes (256, 512, 2560) from system command. I think it is related to my another question. So far the only possible way that I am able to access return code of first command is using qw or backtickss ``. This seems as a a little overkill for me since I need one echo to capture the PIPESTATUS[0] value.

$ perl -e 'my $res = qx/true | false 2>&1 >\/dev\/null; echo \${PIPESTATUS[0]}/; print $res'
0
$ perl -e 'my $res = qx/false | true 2>&1 >\/dev\/null; echo \${PIPESTATUS[0]}/; print $res'
1
$ perl -e 'my $res = qx"false | true 2>&1 >/dev/null; echo \${PIPESTATUS[0]}"; print $res'
1
$ perl -e 'my $res = qx"true | false 2>&1 >/dev/null; echo \${PIPESTATUS[0]}"; print $res'
0
$ perl -e 'my $res = qx(false | true 2>&1 >/dev/null; echo \${PIPESTATUS[0]}); print $res'
1
$ perl -e 'my $res = `false | true 2>&1 >/dev/null; echo \${PIPESTATUS[0]}`; print $res'
1

我也想知道为什么这种方法甚至工作,因为这里中提到,Perl不会调用shell执行外部命令。那么,这是否 PIPESTATUS (这是一个纯粹的bash的变量)从何而来?我也期待下面的命令,因为庆典将工作明确发出,但它没有返回值:

I am also wondering why this approach is even working because here is mentioned that perl does not invoke a shell to execute external command. So where does PIPESTATUS (which is a pure bash variable) comes from? Also I would expect that following command will work since bash is explicitly issued, but it returns nothing:

$ perl -e 'my $res = `bash -c "false | true 2>&1 >/dev/null; echo \${PIPESTATUS[0]}"`; print $res'

$

第三小姐的理解是基于回答,我可以直接访问 PIPESTATUS 通过将其分配给变量,然后变量来访问作为一个普通的Perl变量如:

The third miss understanding is based on this answer that I can directly access PIPESTATUS variable via assigning it to variable and then access as a regular perl variable e.g.

status=(${PIPESTATUS[@]})
print $status

但下面的命令不会为我工作。

However the following command does not work for me.

$ perl -e 'my $res = `false | true 2>&1 >/dev/null;`; status=(${PIPESTATUS[@]})'
syntax error at -e line 1, near "@]}"
Missing right curly or square bracket at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

@EDIT 在回答ThisSuitIsBlackNot,TJD和CapEnt

@EDIT in reply to ThisSuitIsBlackNot, tjd and CapEnt

返回codeS和位数据移位解释说:

Return codes and bit shifting explained:

$ perl -e 'my $code = system("true | false"); print $code >> 8; print "\n"'
1
$ perl -e 'my $code = system("bash -c \"true | false\""); print $code >> 8; print  "\n"'
1
$ perl -e 'my $code = system("bash -c \"exit 2\""); print $code >> 8; print "\n"'
2

某些系统具有 / bin / sh的指出,庆典 ...

# Linux arch 3.18.6-1-ARCH #1 SMP PREEMPT Sat Feb 7 08:59:29 CET 2015 i686 GNU/Linux
$ ls -la `which sh`
lrwxrwxrwx 1 root root 4 Dec 30 23:11 /usr/bin/sh -> bash

$ perl -e 'my $cmd = "exit 255 | true 2>&1 >/dev/null; echo \${PIPESTATUS[0]}"; system($cmd);'
255

有些不是...

some not ...

# SunOS andromeda 5.9 Generic_122300-61 sun4u sparc SUNW,Sun-Fire-V490
$ ls -la `which sh`
-r-xr-xr-x   4 root     root       95504 Jul 16  2009 /bin/sh

$ perl -e 'my $cmd = "exit 255 | true 2>&1 >/dev/null; echo \${PIPESTATUS[0]}"; system($cmd);'
sh: bad substitution

一个小黑客将使用庆典无论是什么的/ bin / sh的指向:

# Linux arch 3.18.6-1-ARCH #1 SMP PREEMPT Sat Feb 7 08:59:29 CET 2015 i686 GNU/Linux
# SunOS andromeda 5.9 Generic_122300-61 sun4u sparc SUNW,Sun-Fire-V490
$ perl -e 'my $cmd = "bash -c \"exit 255 | true 2>&1 >/dev/null; echo \\\${PIPESTATUS[0]}\""; system($cmd);'
255

在这里,您可以看到的bash在这两种情况下调用(在第二种情况庆典是儿童 SH

# Linux arch 3.18.6-1-ARCH #1 SMP PREEMPT Sat Feb 7 08:59:29 CET 2015 i686 GNU/Linux
$ perl -e 'my $code = system("bash -c \"ps -elf | grep $$\"");'
0 S wakatana     1576   282  0  80   0 -  1606 wait   16:46 pts/1    00:00:00 perl -e my $code = system("bash -c \"ps -elf | grep $$\"");
0 S wakatana     1577  1576  0  80   0 -  1333 wait   16:46 pts/1    00:00:00 bash -c ps -elf | grep 1576
0 S wakatana     1579  1577  0  80   0 -  1167 pipe_w 16:46 pts/1    00:00:00 grep 1576

# SunOS andromeda 5.9 Generic_122300-61 sun4u sparc SUNW,Sun-Fire-V490
$ perl -e 'my $code = system("bash -c \"ps -elf | grep $$\"");'
 8 S wakatana 24641 24640  0  60 20        ?    314        ? 16:01:45 pts/196  0:00 bash -c ps -elf | grep 24639
 8 S wakatana 24640 24639  0  50 20        ?    139        ? 16:01:45 pts/196  0:00 sh -c bash -c "ps -elf | grep 24639
 8 S wakatana 24643 24641  0  50 20        ?    128        ? 16:01:45 pts/196  0:00 grep 24639
 8 S wakatana 24639 24633  0  50 20        ?    383        ? 16:01:45 pts/196  0:00 perl -e my $code = system("bash -c

由于ThisSuitIsBlackNot指出,可能是最好的解决办法是使用 IPC ::运行但我想知道如果这是在正常情况下,当我需要单纯的Perl(不含模块)

As ThisSuitIsBlackNot pointed out, probably the best solution is to use IPC::Run but I am wondering if this is OK in case when I need pure perl (without modules)

推荐答案

系统的返回值必须是正确的8移位,如的的perldoc说。这样的:

The return value of system must be shifted right by 8, as perldoc says. Like:

perl -e 'my $code = system("false | true"); print $? >> 8 . "\n"'

这篇关于巴什像PIPESTATUS相当于perl的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆