Simple question, how can I sudo test if a file exists using Net::OpenSSH? I really tried hard to figure this out, but with no result. Ok, I can use a wrapper script, but that's not what I want.

This is my wrapper sub. It works fine most of the time, but it's not testing for files?!

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 ...

I know, I don't have to sudo check a cmd in /usr/local/bin , it's just an example. Of course I also "chomped" the result after &sudo(). such a simple task ... and I'm stuck!

It seems I can't get the command concatenation working: there is an extra argument && warning. The sub always returns undef.

Is this a limitation? Is this supported at all? Using

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

works fine, which is what I'm using right now. So an additional sudo in front should not be that much of a problem ...

Can anyone help?

有帮助吗?

解决方案

The command supplied to sudo works similar like the list form of perl's system() or exec() — that is, without using any shell. So any shell metacharacters like && or || won't work here. To fix this, explicitly use a shell:

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

Alternatively, instead of using capture() you could use Net::OpenSSH's system() instead and just inspect the return value — then there's no need for using && and ||.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top