in reply to Re: Execute command with spaces in perl
in thread Execute command with spaces in perl

Thanks for your suggestion. The '-|", LIST pipe seems not working on Windows. My script should be able to execute seamlessly between Linux and Windows. Instead when I use the STRING pipe, as mentioned here: https://www.perlmonks.org/bare/?node_id=902198, it again breaks splitting on the space: 'C:\Program' is not recognized as an internal or external command, operable program or batch file.

my $cmd = 'C:\Program Files\Mozilla Firefox\firefox.exe --version'; chomp($cmd); open my $fh2, "$cmd|" or die $!; my $out = do { local $/; <$fh2> }; # slurp close $fh2 or die $! ? $! : "\$?=$?"; chomp $out;

Replies are listed 'Best First'.
Re^3: Execute command with spaces in perl
by haukex (Archbishop) on Aug 27, 2018 at 12:52 UTC
    The '-|", LIST pipe seems not working on Windows.
    open my $fh2, "$cmd|" or die $!;
    it again breaks splitting on the space

    I tested my code before posting, and the '-|', LIST form should work on Windows (Update: at least on Perl 5.22 and up). If it's not working for you, please show the code you're trying and the exact error messages you're getting (How do I post a question effectively? and Short, Self-Contained, Correct Example). The code you posted here is not the '-|', LIST form, which it why it isn't working - why aren't you using the code I showed? With a single string argument, you need to do the quoting correctly; I explained the difference between the two in the node I linked to earlier.

    If you need --version to be variable as well, you could do this:

    use warnings; use strict; my @cmd = ('C:\Program Files\Mozilla Firefox\firefox.exe', '--version'); die "\@cmd must have more than one element" unless @cmd>1; open my $fh, '-|', @cmd or die $!; my $out = do { local $/; <$fh> }; # slurp close $fh or die $! ? $! : "\$?=$?"; chomp $out;

    Note I've added the check for @cmd having more than one element to make sure the LIST form is being used.

    If for whatever reason you really need the string form, then you'll have to use better quoting, like what is provided by Win32::ShellQuote, or the other modules I named.

    My script should be able to execute seamlessly between Linux and Windows.

    The code I showed should work fine on both OSes, except of course for the filename of the Firefox executable; if you've having trouble on Linux, again, please show exactly what that trouble is. For platform-independent filename handling, I recommend the core module File::Spec, or with a nicer interface Path::Class.

      For your second example the output on Windows is:

      List form of pipe open not implemented at C:\usr\pm\pipe2.pl line 5.

      This is discussed at this node as mentioned by naveenp5.

        That appears to have been fixed since 2011:

        C:\usr\local\share\PassThru\perl>perl -Mwarnings -Mstrict -MConfig -le + "my $cmd = q|C:\Program Files\Mozilla Firefox\firefox.exe|; open my +$fh, '-|', $cmd, '--version' or die $!; m y $out = do { local $/; <$fh> }; close $fh or die $! ? $! : qq(\$?=$?) +; print $out; print $Config{myuname}" Mozilla Firefox 61.0.2 Win32 strawberry-perl 5.26.2.1 #1 Sun Apr 15 13:52:49 2018 x64

        Trying to narrow it down a bit, using berrybrew to help me, it appears it was sometime between v5.20 and v5.26:

        C:\usr\local\share\PassThru\perl>berrybrew use 5.10.1_32,5.16.3_64,5.2 +0.3_64,5.26.1_32 perl-5.10.1_32 ============== Microsoft Windows [Version 10.0.16299.611] (c) 2017 Microsoft Corporation. All rights reserved. <berrybrew use 5.10.1_32>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>perl -Mwarnings -Mstrict -MConfig -le + "my $cmd = q|C:\Program Files\Mozilla Firefox\firefox.exe|; open my +$fh, '-|', $cmd, '--version' or die $!; m y $out = do { local $/; <$fh> }; close $fh or die $! ? $! : qq(\$?=$?) +; print $out; print $Config{myuname}" List form of pipe open not implemented at -e line 1. <berrybrew use 5.10.1_32>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>exit Exiting <berrybrew use 5.10.1_32> perl-5.16.3_64 ============== Microsoft Windows [Version 10.0.16299.611] (c) 2017 Microsoft Corporation. All rights reserved. <berrybrew use 5.16.3_64>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>perl -Mwarnings -Mstrict -MConfig -le + "my $cmd = q|C:\Program Files\Mozilla Firefox\firefox.exe|; open my +$fh, '-|', $cmd, '--version' or die $!; m y $out = do { local $/; <$fh> }; close $fh or die $! ? $! : qq(\$?=$?) +; print $out; print $Config{myuname}" List form of pipe open not implemented at -e line 1. <berrybrew use 5.16.3_64>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>exit Exiting <berrybrew use 5.16.3_64> perl-5.20.3_64 ============== Microsoft Windows [Version 10.0.16299.611] (c) 2017 Microsoft Corporation. All rights reserved. <berrybrew use 5.20.3_64>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>perl -Mwarnings -Mstrict -MConfig -le + "my $cmd = q|C:\Program Files\Mozilla Firefox\firefox.exe|; open my +$fh, '-|', $cmd, '--version' or die $!; m y $out = do { local $/; <$fh> }; close $fh or die $! ? $! : qq(\$?=$?) +; print $out; print $Config{myuname}" List form of pipe open not implemented at -e line 1. <berrybrew use 5.20.3_64>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>exit Exiting <berrybrew use 5.20.3_64> perl-5.26.1_32 ============== Microsoft Windows [Version 10.0.16299.611] (c) 2017 Microsoft Corporation. All rights reserved. <berrybrew use 5.26.1_32>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>perl -Mwarnings -Mstrict -MConfig -le + "my $cmd = q|C:\Program Files\Mozilla Firefox\firefox.exe|; open my +$fh, '-|', $cmd, '--version' or die $!; m y $out = do { local $/; <$fh> }; close $fh or die $! ? $! : qq(\$?=$?) +; print $out; print $Config{myuname}" Mozilla Firefox 61.0.2 Win32 strawberry-perl-no64 5.26.1.1 #1 Sun Sep 24 11:38:56 2017 i386 <berrybrew use 5.26.1_32>: run "exit" leave this environment C:\usr\local\share\PassThru\perl>exit Exiting <berrybrew use 5.26.1_32>
        List form of pipe open not implemented

        Yes, my update, which I made shortly after posting that node, mentions it: the list from of piped open wasn't implemented on Windows until Perl v5.22. I don't see where naveenp5 mentions that particular error, though? Update: Oh, I see it now (the URL of 902198). I understood that comment to refer to the string pipe, not the error message, but it is a hint that the OP may be on a Perl older than v5.22 - another reason to use a module instead :-)