http://www.perlmonks.org?node_id=1025859

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

Hi, I'm writing a code to fire some commands on powershell.exe and capture the output. For this, I used below code using open function and it worked fine for me -

$input = "date"; $program = "powershell.exe -STA -ExecutionPolicy RemoteSigned -command + -"; $pid = open(WRITEME, "| $program") or die "Couldn't fork: $!\n"; print WRITEME "date\n"; print WRITEME ". ./PowerShell/common/Get-SepmRmmWsAccessToken.ps1 -sym +-383925ff28c -port 8446\n"; print WRITEME "Get-SepmRmmWsAccessToken -HostName 10.211.34.102 -Port +8446 -ClientId 7cbce559-2eca-4ff8-806b-b2e511a239d0 -ClientSecret 729 +05a1c-2953-4607-bb9a-0e92060308b7"; close(WRITEME) or die "Couldn't close: $!\n";

In the above code, all the commands can be passed to powershell.exe but, I can't capture the output that comes once these powershell commands are executed. So, I thought to use open2 function and wrote below code-

use IPC::Open2; $program = "powershell.exe -STA -ExecutionPolicy RemoteSigned -command + -"; open2(*README, *WRITEME, $program) or die "Couldn't fork: $!\n"; print WRITEME "date\n" or die "couldn't write: $!\n"; print WRITEME ". ./PowerShell/common/Get-SepmRmmWsAccessToken.ps1 -sym +-383925ff28c -port 8446\n"; print WRITEME "Get-SepmRmmWsAccessToken -HostName 10.211.34.102 -Port +8446 -ClientId 7cbce559-2eca-4ff8-806b-b2e511a239d0 -ClientSecret 729 +05a1c-2953-4607-bb9a-0e92060308b7"; close(WRITEME) or die "Couldn't close: $!\n"; $output = <README>; print "Content read is:\n----------------\n"; print "$output\n"; print "Content read is:\n----------------\n"; close(README) or die "Couldn't close: $!\n";

This code doesn't capture output in $output variable and I see nothing when I print this $output. Please help me out with this.

Replies are listed 'Best First'.
Re: Child process opened using open function works fine but doesn't work with open2 function
by McA (Priest) on Mar 28, 2013 at 08:30 UTC

    Good morning,

    IMHO the problem lies in the fact that the output of powershell can have more than one line. You simply don't know how much output (linewise) is produced by a command. So you don't know how much lines you have to read until you know you grabed the whole output ready to send the next command. This deadlock behaviour is mentioned by the docs of IPC::Open2.

    So in your case (after a short look at the help screen of powershell) assuming that the startup of the powershell is more or less cheap I recommend to put the commands you want to be executed by powershell on the commandline of powershell or put it into a file to be read from the powershell and only connect STDOUT of the powershell with STDIN of your perl script to read the command's output.

    McA