Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
i am facing problem as stated in title. I need to run bunch of commands but as specific user using sudo-like BoKS mechanism.

What i am trying to acheive is to "redirect" my std[err|out] to other application than regular shell
In shell terms i am trying to run ssh remotehost -t "sx su - root" where "sx" is SuExec command which i need to prepend every privileged operation, or regular 'su' to switch user(just like sudo with NOPASSWD option, but remotely controlled).

Is it possible with Openssh?

Replies are listed 'Best First'.
Re: Net::Openssh spawn other process than shell
by salva (Canon) on Mar 31, 2018 at 07:24 UTC
    my $ssh = Net::OpenSSH->new(...); for my $cmd (@cmds) { $ssh->system('sx', 'su', '-l', $user, '-c', $cmd); }

      Thanks salva for your reply, but it's not quite what i am looking for.
      Think about my sx thingie like it's gnu screen. I would like to ssh 'into' screen directly, instead of launching it as a command.

      i noticed also other thing: while running commands in loop, they're acting like being launched over separate ssh connections. Consider following code

      use strict; use warnings; use Net::OpenSSH; use MIME::Base64; my $host = $ARGV[0]; my $ssh = Net::OpenSSH->new(user => 'user', password => decode_base64('my_b64_encoded_ +pass'), host => $host, timeout => '3', # master_stderr_discard => 1, # master_opts => [-o =>'RemoteCommand="sx s +u - targetuser"'] ); die "Can't ssh to $host: " . $ssh->error if ($ssh->error); foreach my $cmd('echo "VAR=$VAR"', 'id', 'export VAR="test";echo $VAR', 'echo "VAR=$VAR"') { my $output=$ssh -> system ($cm +d); $ssh->error and warn "$cmd didn't complete successfully: ". $ssh->error; print $output; }
      It produces output
      VAR=
      1uid=xxx(user) gid=yyy(group)
      1test
      1VAR=

      I didn't found method which allows "connection" to be kept between system() or capture() calls, or i am doing something awfully wrong.
      My ultimate goal is to check exitcode after each line of (externally loaded) script and perform action if something fails, but without some initializations with exporting variables my whole idea collapses :/
      i don't want to produce nasty workaround like env > /tmp/envfile and sourcing it prior to actual command.

      Does Openssh foresee mechanism to continue/append to existing connection? I love concept of warn $ssh-> error if $ssh-> error, hence i don't want to look for other modules, and surely i don't want to utilize any Expect-like tools.

        Think about my sx thingie like it's gnu screen

        Then, you should look at the options provided by that command for controling its subprocesses.

        I didn't found method which allows "connection" to be kept between system() or capture() calls

        SSH just doesn't work that way. Read Can not change working directory on the module FAQ for an explanation.

        Another option is to use the talk-to-the-shell approach, where you start a remote shell and use its stdio streams to send commands to it and read the output back. But that can be really troublesome as there is not an easy way to know when some remote command has ended other than checking for the shell prompt (which is not very robust).

        BTW, if you want to get the output of the remote commands, you may like to use the capture* methods instead of system.