![]() |
Getting 'system' to Process Win32 Paths Correctly
I wish to supply a user with a Perl distribution which includes a
command-line utility and whose test suite tests the output of that utility. The test suite's call to that utility looks like this: ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"), "able to call command-line utility"); where $^X is the name used to execute the current copy of Perl and $cwd holds the name of the directory from which the test suite is called, i.e., the directory holding Makefile.PL. This works fine on my Unix-style system and fine on Win32 *provided* that $cwd contains no wordspaces. So if the value of $cwd is "C:/temp/other", the 'system' call correctly expands $cwd and the test runs as intended. However, if the value of $cwd is "C:/Documents and Settings/localuser/My Documents", then the only part of the path that get substituted is "C:/Documents". The "and" in "Documents and Settings" is treated by perl as the program to be run, which causes an error. I've looked at the documentation for modules such as Cwd and File::Spec and I don't see a workaround. So, ... Can anyone suggest how to get 'system' to correctly interpret a variable which holds a Win32 path which may contain wordspaces? Thank you very much. Jim Keenan |
Re: Getting 'system' to Process Win32 Paths Correctly
Jim Keenan wrote:
> I wish to supply a user with a Perl distribution which includes a > command-line utility and whose test suite tests the output of that > utility. The test suite's call to that utility looks like this: > > ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"), > "able to call command-line utility"); > > where $^X is the name used to execute the current copy of Perl and $cwd > holds the name of the directory from which the test suite is called, > i.e., the directory holding Makefile.PL. > > This works fine on my Unix-style system and fine on Win32 *provided* > that $cwd contains no wordspaces. So if the value of $cwd is > "C:/temp/other", the 'system' call correctly expands $cwd and the test > runs as intended. I don't think this has anything to do with system(), so much as it has to do with standard command line processing. If there are spaces in a command line, they're taking to be argument-separators. If you want them to mean actual spaces, you have to escape them - either by prepending them with a backslash, or by enclosing the entire argument in quotes: ok(! system(qq|^X -I"$cwd/blib/lib" "$cwd/blib/script/utility"|), "able to call command-line utility" Paul Lalli |
Re: Getting 'system' to Process Win32 Paths Correctly
"Jim Keenan" <jkeen_via_google@yahoo.com> wrote in
news:1121348311.256832.140110@f14g2000cwb.googlegr oups.com: > I wish to supply a user with a Perl distribution which includes a > command-line utility and whose test suite tests the output of that > utility. The test suite's call to that utility looks like this: > > ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"), > "able to call command-line utility"); > .... > However, if the value of $cwd is "C:/Documents and > Settings/localuser/My Documents", then the only part of the path that > get substituted is "C:/Documents". The easy way is to wrap the file name in quotation marks: system("$^X -Iqq{$cwd/blib/lib} qq{$cwd/blib/script/utility}"); On the other hand, for better portability, I would construct the individual paths using File::Spec::catfile anyway. By the way, there is a difference between calling system as above versus system($^X, -I$cwd/blib/lib, $cwd/blib/script/utility); D:\Home\asu1\UseNet\clpmisc> cat ttt.pl #!/usr/bin/perl use strict; use warnings; my $appdata = $ENV{APPDATA}; system "perl t2.pl $appdata"; system 'perl', 't2.pl', $appdata; __END__ D:\Home\asu1\UseNet\clpmisc> cat t2.pl #!/usr/bin/perl use strict; use warnings; print "$_\n" for @ARGV; __END__ D:\Home\asu1\UseNet\clpmisc> ttt C:\Documents and Settings\asu1\Application Data C:\Documents and Settings\asu1\Application Data Read perldoc -f system Sinan -- A. Sinan Unur <1usa@llenroc.ude.invalid> (reverse each component and remove .invalid for email address) comp.lang.perl.misc guidelines on the WWW: http://mail.augustmail.com/~tadmc/cl...uidelines.html |
Re: Getting 'system' to Process Win32 Paths Correctly
"Paul Lalli" <mritty@gmail.com> wrote in
news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com: > Jim Keenan wrote: >> I wish to supply a user with a Perl distribution which includes a >> command-line utility and whose test suite tests the output of that >> utility. The test suite's call to that utility looks like this: >> >> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"), >> "able to call command-line utility"); >> >> where $^X is the name used to execute the current copy of Perl and >> $cwd holds the name of the directory from which the test suite is >> called, i.e., the directory holding Makefile.PL. >> >> This works fine on my Unix-style system and fine on Win32 *provided* >> that $cwd contains no wordspaces. So if the value of $cwd is >> "C:/temp/other", the 'system' call correctly expands $cwd and the >> test runs as intended. > > I don't think this has anything to do with system(), Indeed it does. There is a difference between passing a single scalar string versus a list to system. Sinan -- A. Sinan Unur <1usa@llenroc.ude.invalid> (reverse each component and remove .invalid for email address) comp.lang.perl.misc guidelines on the WWW: http://mail.augustmail.com/~tadmc/cl...uidelines.html |
Re: Getting 'system' to Process Win32 Paths Correctly
A. Sinan Unur wrote:
> "Paul Lalli" <mritty@gmail.com> wrote in > news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com: > > > Jim Keenan wrote: > >> I wish to supply a user with a Perl distribution which includes a > >> command-line utility and whose test suite tests the output of that > >> utility. The test suite's call to that utility looks like this: > >> > >> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"), > >> "able to call command-line utility"); > >> > >> where $^X is the name used to execute the current copy of Perl and > >> $cwd holds the name of the directory from which the test suite is > >> called, i.e., the directory holding Makefile.PL. > >> > >> This works fine on my Unix-style system and fine on Win32 *provided* > >> that $cwd contains no wordspaces. So if the value of $cwd is > >> "C:/temp/other", the 'system' call correctly expands $cwd and the > >> test runs as intended. > > > > I don't think this has anything to do with system(), > > Indeed it does. There is a difference between passing a single scalar > string versus a list to system. Hrm. Good point. Trying to see if I understand perldoc -f system correctly... so if a single string is passed, system lets the shell parse the string into program + arguments, but if a list of more than item is passed, system executes the first element, specifying the remainder as arguments? Good to keep in mind. Thanks for the reminder. Paul Lalli |
Re: Getting 'system' to Process Win32 Paths Correctly
"A. Sinan Unur" <1usa@llenroc.ude.invalid> wrote in
news:Xns969366015F405asu1cornelledu@127.0.0.1: > "Jim Keenan" <jkeen_via_google@yahoo.com> wrote in > news:1121348311.256832.140110@f14g2000cwb.googlegr oups.com: > >> I wish to supply a user with a Perl distribution which includes a >> command-line utility and whose test suite tests the output of that >> utility. The test suite's call to that utility looks like this: >> >> ok(! system("$^X -I$cwd/blib/lib $cwd/blib/script/utility"), >> "able to call command-line utility"); >> > > ... > >> However, if the value of $cwd is "C:/Documents and >> Settings/localuser/My Documents", then the only part of the path that >> get substituted is "C:/Documents". > > The easy way is to wrap the file name in quotation marks: > > system("$^X -Iqq{$cwd/blib/lib} qq{$cwd/blib/script/utility}"); And, this, of course, is wrong. The correct version would have been: system(qq{$^X -I"$cwd/blib/lib" "$cwd/blib/script/utility"}); My other comments regarding passing a list to system, and using File::Spec::catfile to construct paths still apply, though. Sinan -- A. Sinan Unur <1usa@llenroc.ude.invalid> (reverse each component and remove .invalid for email address) comp.lang.perl.misc guidelines on the WWW: http://mail.augustmail.com/~tadmc/cl...uidelines.html |
Re: Getting 'system' to Process Win32 Paths Correctly
A. Sinan Unur wrote:
> The correct version would have been: > > system(qq{$^X -I"$cwd/blib/lib" "$cwd/blib/script/utility"}); > > Thanks, Sinan, this DWIMmed. A note for further reference: To pare the original question down to its essence, I omitted options that the command-line utility would normally call. When I tested the real code, I had to add them back in. The quoting that worked for them went like this: ok(! system(qq{$^X -I"$cwd/blib/lib" "$cwd/blib/script/utility" -Icn XYZ::ABC}), "able to call utility"); Note that the option flags and arguments are not placed within the quotation marks, but are still within the scope of the 'qq{}'. Jim Keenan |
Re: Getting 'system' to Process Win32 Paths Correctly
A. Sinan Unur wrote:
> "Paul Lalli" <mritty@gmail.com> wrote in > news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com: >> >>I don't think this has anything to do with system(), > > Indeed it does. There is a difference between passing a single scalar > string versus a list to system. Except this is Win32 - where there isn't a difference. system(LIST) effectively joins the list with spaces and the CLI splits it again (in all the wrong places). |
Re: Getting 'system' to Process Win32 Paths Correctly
Brian McCauley <nobull@mail.com> wrote in news:db8pri$f8g$1
@redhat2.bham.ac.uk: > A. Sinan Unur wrote: > >> "Paul Lalli" <mritty@gmail.com> wrote in >> news:1121349105.502877.106680@g44g2000cwa.googlegr oups.com: > >> >>>I don't think this has anything to do with system(), >> >> Indeed it does. There is a difference between passing a single scalar >> string versus a list to system. > > Except this is Win32 - where there isn't a difference. > > system(LIST) effectively joins the list with spaces and the CLI splits > it again (in all the wrong places). I am not sure if you noticed my earlier example. Here is another one of system(SCALAR) versus system(LIST). There clearly is a difference. D:\Home\asu1\UseNet\clpmisc> cat hello.c #include <stdio.h> int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; ++i) { printf("%s\n", argv[i]); } } D:\Home\asu1\UseNet\clpmisc> cl hello.c Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 Copyright (C) Microsoft Corporation 1984-2002. All rights reserved. hello.c Microsoft (R) Incremental Linker Version 7.10.3077 Copyright (C) Microsoft Corporation. All rights reserved. /out:hello.exe hello.obj D:\Home\asu1\UseNet\clpmisc> cat ttt.pl #!/usr/bin/perl use strict; use warnings; system "hello A. Sinan Unur ---"; system 'hello', 'A. Sinan Unur', '---'; D:\Home\asu1\UseNet\clpmisc> ttt.pl hello A. Sinan Unur --- hello A. Sinan Unur --- Sinan -- A. Sinan Unur <1usa@llenroc.ude.invalid> (reverse each component and remove .invalid for email address) comp.lang.perl.misc guidelines on the WWW: http://mail.augustmail.com/~tadmc/cl...uidelines.html |
| All times are GMT. The time now is 06:48 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.