Re^2: Executing perl program from another perl program and capturing the output
by Loops (Curate) on Nov 25, 2014 at 04:30 UTC
|
Hi BrowserUk,
It is my recollection that others have explicitly recommended the list form of system on Windows. Could you explain why it isn't helpful, so i'll not recommend it again in error?
| [reply] |
|
ould you explain why it isn't helpful,
Because CreateProcess() is the only way to spawn a new process on windows; and it only accepts a single string containing the runtime arguments.
If you supply system with the list form of arguments, they just get concatenated together, before being passed as the second argument to CreateProcess().
There is some attempt to apply intelligence to the concatenation process, but is does not handle paths with spaces (correctly):
win32_spawnvp(int mode, const char *cmdname, const char *const *argv)
{
#ifdef USE_RTL_SPAWNVP
return spawnvp(mode, cmdname, (char * const *)argv);
#else
dTHXa(NULL);
int ret;
void* env;
char* dir;
child_IO_table tbl;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
DWORD create = 0;
char *cmd;
char *fullcmd = NULL;
char *cname = (char *)cmdname;
STRLEN clen = 0;
if (cname) {
clen = strlen(cname);
/* if command name contains dquotes, must remove them */
...
About the dumbest thing it could do...
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
Interesting. Thanks.
I did see the following in the System docs:
On Windows, only the system PROGRAM LIST syntax will reliably avoid using the shell; system LIST , even with more than one element, will fall back to the shell if the first spawn fails.
And was thinking mistakenly that array flattening would suffice. It appears that if "USE_RTL_SPAWNVP" is defined, that horror show is avoided though yes? A quick look in the code didn't reveal if that's true or if it's even defined in the common case. But fwiw, I did see a note in the code recommending Win32::Process instead.
| [reply] |
|
| [reply] [d/l] |
Re^2: Executing perl program from another perl program and capturing the output
by Anonymous Monk on Nov 25, 2014 at 03:41 UTC
|
The list form of system won't help you on windows. If your paths don't include quotes, system can help you on windows, if you use Capture::Tiny
use Capture::Tiny qw/ capture /;
my($stdout, $stderr, $exit) = capture {
system { $args[0] } @args;
};;
If you have quotes in your paths then Win32::ShellQuote comes to the rescue | [reply] [d/l] |
|
C:\test>"c:\Program Files\Direct Modeling Express 4.0\binx64\7za.exe"
+a -y c:\junk.rar "c:\Program Files\Hitman Pro 3.5\*"
7-Zip (A) 4.42 Copyright (c) 1999-2006 Igor Pavlov 2006-05-14
Scanning
Creating archive c:\junk.rar
Compressing HitmanPro35_x64.exe
Everything is Ok
Then invoking the same command via the shell, via backticks also requires, (and will work with) quotes ... (but use / instead of \ for paths!) [0] Perl> $output = `\"c:/Program Files/Direct Modeling Express 4.0/bi
+nx64/7za.exe\" a -y c:/junk.rar \"c:/Program Files/Hitman Pro 3.5/*\"
+`;;
[0] Perl> print $output;;
7-Zip (A) 4.42 Copyright (c) 1999-2006 Igor Pavlov 2006-05-14
Scanning
Updating archive c:/junk.rar
Compressing HitmanPro35_x64.exe
Everything is Ok
And that's *all* that is required. No ifs; no buts; learn the rules, and it just works.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
And that's *all* that is required. No ifs; no buts; learn the rules, and it just works. Yeah, I stick to learning perl quoting rules, and then don't worry about cmd.exe quoting rules too much
| [reply] |
|
Re^2: Executing perl program from another perl program and capturing the output
by rgren925 (Beadle) on Nov 29, 2014 at 23:12 UTC
|
This was exactly what I needed.
I had tried just about every combination of quotes and escaped quotes BUT this, naturally.
I had tried Win32:GetShortPathName and it worked but, as this is a cross-platform tool, I prefer to avoid platform-specific code paths where possible.
Thanks very much!
| [reply] |
|
I had tried Win32:GetShortPathName and it worked but, as this is a cross-platform tool, I prefer to avoid platform-specific code paths where possible.
Indeed. I don't have to write cross-platform very often, and I have no problem using well-written modules when required.
But unlike many others (it seems), my criteria for "when required" extends well beyond 'it exists'. If I don't need it, I don't use it(*).
I like simple! (Which my wife would probably say, is just as well ... :)
There are very good reasons for keeping ones dependencies to a minimum.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |