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

Hello All,

I have an interactive shell command, let's call it xyz. It unfortunately doesn't accept command line arguments and commands can be sent only once we enter into the xyz shell.

Is there a way to run this shell from a perl script and enter commands for it? I usually use system to call functions as though they are typed in the terminal window. But I am unable to use this for my current problem. It would be great if you are able to provide any inputs.

Replies are listed 'Best First'.
Re: Run an interactive shell command from Perl script
by marto (Cardinal) on Sep 26, 2018 at 21:55 UTC

    Greetings, have you considered Expect?

Re: Run an interactive shell command from Perl script
by Laurent_R (Canon) on Sep 26, 2018 at 21:58 UTC
Re: Run an interactive shell command from Perl script
by choroba (Cardinal) on Sep 27, 2018 at 11:27 UTC
    If sending commands to the standard input of the command works, you can
    open my $cmd, '|-', 'xyz' or die $!; print {$cmd} "command1\n"; print {$cmd} "command2\n";

    If you need to read the output of the command, too, see IPC::Open2.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Run an interactive shell command from Perl script
by zentara (Cardinal) on Sep 27, 2018 at 18:51 UTC
    Hi, this may help you. The example shows how to run the 'bc' calculator program, and collect its output with IO::Select.
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; my $pid = open3(\*WRITE, \*READ,\*ERROR,"bc"); my $sel = new IO::Select(); $sel->add(\*READ); $sel->add(\*ERROR); my($error,$answer)=('',''); while(1){ print "Enter command\n"; chomp(my $query = <STDIN>); #send query to bash print WRITE "$query\n"; foreach my $h ($sel->can_read) { my $buf = ''; if ($h eq \*ERROR) { sysread(ERROR,$buf,4096); if($buf){print "ERROR-> $buf\n"} } else { sysread(READ,$buf,4096); if($buf){print "$query = $buf\n"} } } } waitpid($pid, 1); # It is important to waitpid on your child process, # otherwise zombies could be created.
    and here is a simple way to start a bash script session, print commands to it, and collect output.
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; $|=1; my $pid=open3(\*IN,\*OUT, \*ERR , '/bin/bash'); # set \*ERR to 0 to send STDERR to STDOUT my $cmd = 'date'; #send cmd to bash print IN "$cmd\n"; my $result = <OUT>; print $result;

    I'm not really a human, but I play one on earth. ..... an animated JAPH