Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Need help with IPC::run3

by freonpsandoz (Beadle)
on Mar 11, 2022 at 02:55 UTC ( #11141989=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to execute external commands that may need Unicode pathnames, from a Perl script on Windows. Please see https://perlmonks.org/?node_id=11141819, where it was suggested that I try using IPC::run3 to pass parameters. I haven't been able to get it to work. The fact that I get the same result whether or not I include the parameter list makes me believe that the parameters aren't being passed to sacd_extract.exe. What am I doing wrong? Thanks.

Code:

use v5.16; use strict; use warnings; use open qw(:std :utf8); # Set the default encoding for STDIN, STDOUT +& STDERR to UTF-8 use IPC::Run3 qw( run3 ); my $filepath = shift; my @extractcmd1 = qw( sacd_extract.exe ); my @tempoutput1 = GetCommandOutput( @extractcmd1 ); my @extractcmd2 = qw( sacd_extract.exe --print --export-cue ); my @tempoutput2 = GetCommandOutput( @extractcmd2, qq(input=$filepath) +); open( my $fh, ">:raw", "run3.txt" ); print( $fh "~~~$_" ) foreach (@tempoutput2); sub GetCommandOutput # (command-string [, params]) { my $stdout = ''; my $stderr = ''; my $exe = $_[0]; print "Command: "; print qq('$_' ) foreach (@_); print "\n"; eval { run3 \@_, \undef, \$stdout, \$stderr }; if ( $@ ) { say "$exe error: $@"; } elsif ( $? & 0x7F ) { say "$exe killed by signal ".( $? & 0x7F ); } elsif ( $? >> 8 ) { say "$exe exited with error ".( $? >> 8 ); } else { say "$exe completed successfully"; } say "stdout=$stdout"; say "stderr=$stderr"; return map { chomp; $_ } split(/\n/, $stdout); }

Output

D:\test>perl -S test-run3.pl "E:\Temp\Greatest Hits.iso" Command: 'sacd_extract.exe' sacd_extract.exe completed successfully stdout= stderr=No such file or directory libsacdread: Can't stat /dev/cdrom Command: 'sacd_extract.exe' '--print' '--export-cue' 'input=E:\Temp\Gr +eatest Hits.iso' sacd_extract.exe completed successfully stdout= stderr=No such file or directory libsacdread: Can't stat /dev/cdrom

UPDATE: Oops, I accidentally left out '--' on 'input='; that's why this one didn't work. That sample script is working now, but the one I'm really trying to get working is this one:

use v5.16; use strict; use warnings; use open qw(:std :utf8); # Set the default encoding for STDIN, STDOUT +& STDERR to UTF-8 use Encode qw( decode ); use IPC::Run3 qw( run3 ); use constant CORECONVERTEREXE => 'C:\Program Files\dBpoweramp\coreconv +erter.exe'; my $filepath = shift; my @convcmd = ( "${\CORECONVERTEREXE}", "-outfile=nul", "-convert_to=wave", "-erro +rfile=core.err", qq(-infile=$filepath) ); my $tempoutput1 = decode( 'UTF-16LE', GetCommandOutput(@convcmd) ); print "$tempoutput1\n"; sub GetCommandOutput # (command-string [, params]) { my $stdout = ''; my $stderr = ''; my $exe = $_[0]; print "Command: "; print qq('$_' ) foreach (@_); print "\n"; eval { run3 \@_, \undef, \$stdout, \$stderr }; if ( $@ ) { say "$exe error: $@"; } elsif ( $? ) { say "$exe exited with code $?"; } else { say "$exe completed successfully"; } return $stdout; }

Output:

D:\test>perl -S test-run3conv.pl "E:\Temp\Greatest Hits.iso" Command: 'C:\Program Files\dBpoweramp\coreconverter.exe' '-outfile=nul +' '-convert_to=wave' '-errorfile=core.err' '-infile=E:\Temp\Greatest +Hits.iso' C:\Program Files\dBpoweramp\coreconverter.exe exited with code 256 dBpoweramp Music Converter (C) 2021 Illustrate Ltd Encoding: wave" Audio Source: E:\Temp\Greatest Audio Destination: nul" 0%-----------25%-----------50%-----------75%-----------100%

Replies are listed 'Best First'.
Re: Need help with IPC::run3
by haukex (Archbishop) on Mar 11, 2022 at 04:38 UTC
    Encoding: wave" Audio Source: E:\Temp\Greatest Audio Destination: nul"

    That makes it seem like a quoting issue I think. Unfortunately that's a nontrivial issue on Windows since, unlike *NIX, the command being called could be at fault too. Could you make sure you have the latest versions of IPC::Run3 and Win32::ShellQuote installed, and set the environment variable IPCRUN3DEBUG=1 and report the output of that?

Re: Need help with IPC::run3
by haukex (Archbishop) on Mar 11, 2022 at 12:48 UTC
    dBpoweramp Music Converter

    The examples I've found for coreconverter.exe show that it apparently expects the quoting on the values of the options, not over the entire options, which may explain why it's having trouble parsing the option string, since the default behavior of Win32::ShellQuote as used by IPC::Run3 is to produce option strings that look like ... "-outfile=nul" "-convert_to=wave" .... Although this is not the prettiest solution, you might try something like the following (I obviously can't fully test this since I don't have dBpoweramp).

    use warnings; use strict; BEGIN { $ENV{IPCRUN3DEBUG} = 1 } use IPC::Run3 'run3'; use Win32::ShellQuote qw/quote_system_string/; my $filepath = shift; my $command = join ' ', quote_system_string("C:\\Program Files\\dBpoweramp\\coreconverter. +exe"), "-outfile=".quote_system_string("nul"), "-convert_to=".quote_system_string("wave"), "-errorfile=".quote_system_string("core.err"), "-infile=".quote_system_string($filepath); run3 $command;

    The command run will look like this, which I think has a better chance of working: "C:\Program Files\dBpoweramp\coreconverter.exe" -outfile="nul" -convert_to="wave" -errorfile="core.err" -infile="C:\Temp\Foo Bar"

    By the way, have you looked at FFmpeg?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11141989]
Approved by kcott
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2022-08-18 01:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?