in reply to Re: Expect receives no output, when requested via HTML
in thread Expect receives no output, when requested via HTML

If have executed the following code with input redirected to dev/null

my @cmds = ("sh int des"); # define comma +nds. my @hosts = ("XXX", "XXX"); # define hosts. my @params = (\@cmds, \@hosts); # construct pa +rameter array (currenlty mandatory for execution in a sub process). my $job = new Job(\&exec_on_each, \@params); # define job Dispatcher::query_job($job); # add jobs to +the dispatchers queue. my @out = Dispatcher::execute_jobs(); # execute all +jobs and retieve the result. print Tools::to_string(\@out); # print the re +sult in the console.
Surprisingly this returns the result as expected. I think the user that executes the script via the website has insufficent rights to start SSH.

Replies are listed 'Best First'.
Re^3: Expect receives no output, when requested via HTML
by Corion (Patriarch) on Nov 24, 2020 at 14:28 UTC

    You launch ssh without an absolute path name.

    Have you made sure that $ENV{PATH} is the same when run via the web server as when run via the console?

    Have you inspected the error message you get? $exp->error() might provide more information...

      Thank you so much for your assistance! The subprocess that starts the ssh connection set the $ENV{"PATH"} = "/usr/bin"; (required by expect because of possible tainted return) The $exp->error() returns -1 after each interaction. Unfortuantly i'm very limited on the system i use, and i do not have access to Net::SSH::Any or IPC.
      # assigns a job to a worker process. # :param 0: job. # :return: sub assign_job { my ($job) = @_; my $pid = open my $pipe => "-|"; # create worke +r process and connect it using a pipe. Debug::dlog("spawned process : $pid"); die "Failed to fork: $!" unless defined $pid; # check that c +reation was successfull. my $routine = $job->get_routine(); # get routine +to execute. my $params = $job->get_params(); # get paramete +rs to pass. unless ($pid) { # the followin +g code is only executed in the worker process: $ENV{"PATH"} = "/usr/bin"; # delete conte +xt. my $return = $routine->(@$params); # execute rout +ine. my $dump = Dumper($return); # serialize th +e returned object. print($dump); # print data s +tring to pipe. Debug::dlog("process ".$$." dumped ".length($dump)." chars"); exit; # terminate pr +ocess. } else { # only in pare +nt process: my $worker = new Worker($pipe, $pid); # construct ne +w worker object. push(@Dispatcher::workers, $worker); # save worker +object. } }

        I think you can still remove Expect from the equation if you can manage a passwordless setup, by providing all the input to SSH via STDIN:

        use File::Temp 'tempfile'; my ($fh, $output) = tempfile(); close($fh); open my $remote, "| ssh $user\@$hostname >$tempfile" or die "Couldn't launch ssh ssh $user\@$hostname: $!"; print $remote "some test command\n"; print $remote "another test command\n"; print $remote "quit\n"; open my $fh, '<', $tempfile or die "Couldn't read the tempfile?!"; while(<$fh>) { print "Remote: $_"; };

        But if you need to provide the password to SSH, there is no way to do that without Expect. All of this hinges on the idea of using (passwordless) ssh keys.