pjf / ipc-system-simple

Perl module to make running system commands and capturing errors as simple as possible.
http://search.cpan.org/perldoc?IPC::System::Simple
Other
19 stars 20 forks source link

Windows Failure with Spaces in Path #9

Open Smylers opened 10 years ago

Smylers commented 10 years ago

Hi. I'm finding IPC::System::Simple's system isn't a drop-in replacement for the built-in system in some circumstances involving spaces in a filename being supplied to a command.

For instance, this works, opening or focussing an Explorer window on C:\Program Files:

C:\>perl -E "system qw<cmd /C start /D>, 'C:\Program Files', '.'"

but substituting in IPC::System::Simple's system makes it fail:

C:\>perl -MIPC::System::Simple=system -E "system qw<cmd /C start /D>, 'C:\Program Files', '.'"
The system cannot find the file Files.
"cmd" unexpectedly returned exit value 1 at -e line 1

That also pops up an error box with the message “Windows cannot find 'Files'. Make sure you typed the name correctly, and then try again.”

This doesn't happen with all circumstances in which arguments have spaces in them; it may even be specific to the start command, but clearly what IPC::System::Simple is doing is having some influence on it.

Let me know if there's anything further I can help with.

pjf commented 10 years ago

Smylers, you fabulous and amazing person! You have excellent timing!

Which version of Windows are you using? It looks like cmd changed its behaviour at some point, and I think I have a fix, but I would love a tester. :)

(Let me now get said fix into git to see if it helps.)

~ Paul

Smylers commented 10 years ago

Windows 7 — sorry, should've thought to include that

pjf commented 10 years ago

Patch applied! Any chance you can test what's currently in git (with 1d99f777afccb11a5c735325f78d2034a39e5e0f applied), or this tarball (which is the same, but already built so there's not futzing with dzil).

Many, many thanks!

Smylers commented 10 years ago

Unfortunately that doesn't help: I get the same behaviour as with 1.25.

pjf commented 10 years ago

Ah, because we have spaces in our argument, and not our command. Creating commands on Windows is tricky, because one can't pass in individual arguments, one passes a "command line" to Win32::Process::Create().

I feel this should just be a matter getting ISS to add quotes to its arguments, but I've got a sinking suspicion that's obvious, simple, and wrong. I have a bit of a gotcha here in that I don't presently have easy access to a Windows machine.

Does running cmd /C start /D C:\Program Files . directly in the Windows shell do the right thing, or does it come up with the same error? (I'd expect one would need to quote C:\Program Files)

Now digging into the Perl core to see how it's done there, although since it's 2am localtime I may not have anything to report tonight.

Smylers commented 10 years ago

Correct, the quotes are needed at the Windows shell.

And indeed sticking quotes into the argument passed to system does work (both core's and yours). But it feels icky to have to put quotes into an argument that's documented as not being passed to the shell — and I wasn't confident I knew how to quote the name correctly in the general case.

I'm not sure what the International Space Station has to do with anything, but my Windows knowledge is flaky, and nothing would surprise me at this stage.

Incidentally, the reason I'm opening Explorer in such a convoluted way in the first place is because a simple explorer $dir opens a new window each time (which irritates users), whereas if there's already an Explorer window open on $dir, start $dir will just switch to it. But start isn't a program, it's a built-in command in cmd, hence the need to wrap it. And, astonishingly, start "$dir" fails if $dir contains a space! (No error message, but it just opens another Command Prompt window.) However, that limitation doesn't apply to its /D option, so telling it to start to start in $dir and then open . actually does what's required, despite seeming like at least 2 levels of overkill. I can no longer remember what possessed me to try it.

Good luck.

Smylers commented 10 years ago

It turns out that the built-in system may be buggy on Windows: this recent Perl 5 ticket includes a discussion in which there seems to be general agreement that it's argument-splitting isn't quite right: https://rt.perl.org/Public/Bug/Display.html?id=121283#txn-1282174

There's no suggestion of a fix yet, but it seems possible that system's behaviour on Windows may change.

So it may not be worth making IPC::System::Simple compatible with its current behaviour — especially if it turns out that what IPC::System::Simple currently does it what built-in system will be switching to.

glasswalk3r commented 6 years ago

Just step into this issue because I was searching for a solution for the same problem but with IPC::Run module. The think is that putting the command line with spaces between double quotes and submitting it to run through IPC::Open3 works as expected.

jkeenan commented 4 years ago

I believe that this issue may be resolved in IPC-System-Simple version 1.30, just released to CPAN. Can you confirm?

Thank you very much. Jim Keenan