Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Getting 'system' to Process Win32 Paths Correctly

Reply
Thread Tools

Getting 'system' to Process Win32 Paths Correctly

 
 
Jim Keenan
Guest
Posts: n/a
 
      07-14-2005
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

 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      07-14-2005
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

 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-14-2005
"Jim Keenan" <(E-Mail Removed)> wrote in
news:(E-Mail Removed) 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 <(E-Mail Removed)>
(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
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-14-2005
"Paul Lalli" <(E-Mail Removed)> wrote in
news:(E-Mail Removed) 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 <(E-Mail Removed)>
(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
 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      07-14-2005
A. Sinan Unur wrote:
> "Paul Lalli" <(E-Mail Removed)> wrote in
> news:(E-Mail Removed) 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

 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-14-2005
"A. Sinan Unur" <(E-Mail Removed)> wrote in
news:Xns969366015F405asu1cornelledu@127.0.0.1:

> "Jim Keenan" <(E-Mail Removed)> wrote in
> news:(E-Mail Removed) 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 <(E-Mail Removed)>
(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
 
Reply With Quote
 
Jim Keenan
Guest
Posts: n/a
 
      07-14-2005
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

 
Reply With Quote
 
Brian McCauley
Guest
Posts: n/a
 
      07-15-2005
A. Sinan Unur wrote:

> "Paul Lalli" <(E-Mail Removed)> wrote in
> news:(E-Mail Removed) 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).

 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-16-2005
Brian McCauley <(E-Mail Removed)> wrote in news:db8pri$f8g$1
@redhat2.bham.ac.uk:

> A. Sinan Unur wrote:
>
>> "Paul Lalli" <(E-Mail Removed)> wrote in
>> news:(E-Mail Removed) 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 <(E-Mail Removed)>
(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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Paths, gentleman, paths Ohad Lutzky Ruby 2 11-07-2006 02:15 AM
win32 process information, using win32 extension Java and Swing Python 1 10-24-2005 09:13 PM
RE: win32 process information, using win32 extension Tim Golden Python 0 10-21-2005 02:18 PM
(Win32) Timing out a process while reading process' output? rtm Perl 0 09-27-2004 10:06 PM
Convert between Windows style paths and POSIX style paths Noah Python 5 07-11-2003 09:25 PM



Advertisments