使用Perl Net :: OpenSSH sudo测试文件是否存在,使用命令连接

时间:2013-09-14 22:33:19

标签: perl openssh file-exists

简单的问题,如果使用Net::OpenSSH存在文件,我该如何测试?我真的很努力想出这个,但没有结果。好的,我可以使用包装器脚本,但这不是我想要的。

这是我的包装子。它大部分时间都可以正常工作,但它没有测试文件?!

sub sudo {
    my $f   = shift;
    my $h   = shift;
    my $cmd = shift;       
    my @out = $f->{ssh}->capture( 
        { stdin_data => ["$f->{pwd}\n", @$h ] },
        '/usr/bin/sudo','-Sk','-p','','--',
        @{$cmd}
    );

    return \@out;
}

&sudo($f, [], ['test', '-e', '/user/local/bin/cmd', '&&', 'echo', '1', '||', 'echo', '0']); # <= fails
&sudo($f, [], ['test -e /user/local/bin/cmd && echo 1 || echo 0']); # <= fails too
... # arbitrary other $str/$array combinations ...

我知道,我不必在/usr/local/bin中检查cmd,这只是一个例子。当然我也是&#34; chomped&#34; &sudo()之后的结果。  这么简单的任务......我被卡住了!

似乎我无法使命令连接起作用:有一个extra argument &&警告。子总是返回undef

这是一个限制吗?这支持了吗?使用

$f->{ssh}->capture('test -e /user/local/bin/cmd && echo 1 || echo 0');

工作正常,这就是我现在正在使用的。因此,前面的额外sudo不应该是一个很大的问题......

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

提供给sudo的命令与perl的system()exec()的列表形式类似 - 也就是说,不使用任何shell。因此,&&||等任何shell元字符都不起作用。要解决此问题,请明确使用shell:

sudo($f, [], ['sh', '-c', 'test -e /user/local/bin/cmd && echo 1 || echo 0']);

或者,您可以使用capture()的{​​{1}}而不是使用Net::OpenSSH,而只需检查返回值 - 然后就不需要使用system()和{{ 1}}。