Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^3: Windows System Command

by BrowserUk (Patriarch)
on Jun 27, 2012 at 13:42 UTC ( [id://978664]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Windows System Command
in thread Windows System Command

I find it really odd that arg slots would matter.

The Anonymonk is correct in that traditionally on *nix systems, command lines are broken up on whitespace and each whitepsce delimited token is passed to the process in a separate entry in the char *argv[] array.

So, what you view as the (single) parameter -p pass, actually gets passed into the process as two separate strings in successive entries in argv[].

However, all that is by the by on windows systems because Windows passes the entire command line to the process as a single string. Essentially, exactly as the user typed it with some obscure, minor exceptions.

And traditionally on *nix, when passing parameters to system as a list, each item in the list is placed into a element of argv[] uninspected. Which means that if what you pass is; "-p pass" as a single item in the list, that is how the process will receive it. The trouble is, when the program processes that, it will see the '-p' in (say) argv[5], and then inspect the next item argv[6] looking for "pass" and not find it.

But when you use the list form of system on Windows, the Perl runtime has to concatenate all the items together into a single string in order to pass it to the program being started. The Perl runtime makes some attempts to do this intelligently, but it often gets it wrong.

Which is why I advocate not using the list form of system on Windows. It is usually much easier to cut an actually command line -- tested and known to work -- from a console session and paste it into q[].

Of course, sometimes, some elements of the command line used are not constants and it becomes necessary to interpolate (or concatenate) them with the constant bits to form the command line. In that case, a little more effort is required.

Using your example, say that user, pass and the IP needed to be derived from variables. I'd do it this way. I'd start by getting the command right on the command line:

"C:\\Program\ Files\\HP\ Remote\ System\ Management\\hprsmcli" -s 143. +207.48.60 -u user -p pass

Then I paste that into the program and quote the various bits individually and join then with spaces:

system( join ' ', '"C:\\Program\ Files\\HP\ Remote\ System\ Management\\hprsmcli"', '-s', '143.207.48.60', '-u', 'user', '-p', 'pass' );

Note the use of single quotes, avoiding accidental interpolation and allowing the retention of the required double quotes around the program path without escaping.

Having checked that it works with the parameters hardcoded, it then becomes a simple step to replace the constants with variables where applicable:

system( join ' ', '"C:\\Program\ Files\\HP\ Remote\ System\ Management\\hprsmcli"', '-s', $ip, '-u', $user, '-p', $pass );

Now, the only thing left to deal with is parameters that themselves can contain spaces, like filepaths. Example:

system( join ' ', '"C:\\Program\ Files\\HP\ Remote\ System\ Management\\hprsmcli"', '-s', $ip, '-u', $user, '-p', $pass, '--log', qq["$logfile"] );

Note: There are various other ways of quoting the path, including using backslashed quotes inside double quotes or using concatenation, but qq[] is what I find the clearest for this.

For shorter commands, I would use qq[] alone when necessary:

qq[ "c:\\perl 64\bin\perl.exe" -nle"/this/ and print" "..\some file wi +th spaces.txt" ];
but that can get unweildy for long commands.

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.

The start of some sanity?

Replies are listed 'Best First'.
Re^4: Windows System Command
by Ransom (Beadle) on Jun 27, 2012 at 14:49 UTC
    Well I'm back in my place :) Thanks for this extended response. It's really helping my understanding of some of this underlying material.
Re^4: Windows System Command
by Anonymous Monk on Jun 27, 2012 at 19:27 UTC

    However, all that is by the by on windows systems because Windows passes the entire command line to the process as a single string.

    You know, as a *nix person, I found the function signature for CreateProcess shocking. "How is that better than fork()? It's not going to be easy to make it do anything similar!"

    (I was trying to write an IPC test program and had the bright idea of putting the two halves in the same .exe. Which would not be any problem whatsoever on *nix.)

    Ah well, WINAPI is strange and alien to me.

      "How is that better than fork()?

      It's not better than fork(), just different. It's closer to exec(3).

      For some uses, those typified by the fork&exec pattern, CreateProcess() can be said to be better. Why bother duplicating (even minimal) information and data from the current process if the next thing you are going to do is throw almost all of it away to do the exec.

      For other uses, fork comes into its own. Like airplanes and helicopters, they both achieve similar goals; they just approach them from different angles.

      I've often wished that WinAPI had a proper built-in fork. It wouldn't be hard to add it internally to the OS. I think the reason it doesn;t exist is more political than practical.

      Hell, it's almost(*) possible using the published API's, including COW and the other subtleties, there is just a soupçon of missing functionality that prevents it being done efficiently as a third-party library.

      (*)I'm aware that both cygwin (and that MS toolkit I've forgotten the name of) provide such an api, but only in the context of a POSIX(1) emulation layer and they are not (even vaguely) efficient.


      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.

      The start of some sanity?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://978664]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2024-03-28 19:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found