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