Need perl help re: "system" function

Here’s my code fragment:

The output when I do “perl fubar.pl” is:

C:\windows\system32\cmd.exe /c echo testing 123

at the command line works properly, of course. I can see there’s a quoting problem here, but I don’t know how to fix it. What am I doing wrong?

Thanks!

It’s telling you right in the error message:
‘echo[SPACE]’ is not a recognized command.

Lose the space.

Now I get

Which is not exactly what I’m looking for either. :slight_smile: Why am I getting one double-quote?

And notice in the print line, “echo” and “testing” do not have a space between them. :confused:

This is Windows XP and Perl5, by the way.

Hmmm, reading the man page, I see that “the list is split into words and passed directly to execvp” so I guess that explains it. I was putting the space in to make it look right in the print statement, but the behavior of system is different.

Unfortunately, in the actual code I’m trying to write, this is a subroutine, and I’m passing it a variable, which is a string that contains spaces–and then I get the wrong arguments passed to the command. Any way around that?

Still don’t understand why I get one double-quote in my echo’d statement.

Dang it, I hate it when I’m dense.

Seem to me you want to pass the string “echo testing 123” as a single parameter to cmd.exe:
@command = ("C:\windows\system32\cmd.exe “,”/c ",“echo testing 123”);

  • To print the statement, you want to print the array joined with spaces, not just the array. Do this:
    print join(" ", @command) . "
    ";
  • Get rid of all the extra spaces. Format things for the computer, then mess with them if you need to display them properly (e.g. by using join)
  • The quote may be an artifact of the way the program is called with an argument that has spaces in it. When passing an argument that has spaces, you need to use quotes. For example, this command line:
    dir “my folder”

Echo may not like the quotes the same way, I don’t really care enough about DOS to know. It will probably behave properly if you are invoking a different program and you really want the “testing 123” to be considered as one argument. If you want it to be considered as two arguments, then split it in the command array, like this:

@command = (“C:\windows\system32\cmd.exe”,"/c",“echo”,“testing”, “123”);

Bottom line: Do not format strings in a computer interpreted string for spacing and alignment. Format it for the computer’s benefit, then do the work to present it nicely if you need to.

Terminus made me notice something: Is there a reason you are invoking cmd? Can you invoke echo (or whatever your actual goal is) directly?

Start from the inside & work out. You’ve got too many layers executing now to see the real problem.

Also, using echo as a test harness doesn’t really give you enough intofrmation to see what’s happening.

My advice:

In general cmd.exe parses parameters on spaces, so if you want cmd to execute some program or cmd/bat file you wrote which takes 3 parameters, each of which may contain spaces, then you need to call your program like this

C:>Myprog.exe “parameter 1 with embedded spaces” “param2 is the same” “param 3”

One challenge doing it this way is that the quotes around parameters are passed into the program as well.

Create this simple test harness to see what I mean:



@echo off
:top
if {%1} =={} goto :EOF
echo param={%1}
shift
goto :top


Just save it as “TestHarness.cmd” & try calling it manually directly from the command line with various combinations of quotes, spaces, etc.
e.g.



C:>TestHarness.cmd abc def
C:>TestHarness.cmd "abc" "def"
C:>TestHarness.cmd "abc 1234" " def 567 "
C:>TestHarness.cmd "abc "" 1234" " def 567 "


Also make sure to see how it handles unmatched quotes so you’ll know what you have to do upstream of the call to handle any embedded quotes in the parameters you’d like to pass into your function.
When you get that behavior understood, then try

C:>cmd /c TestHarness.cmd …
for various combinations of paramters. You should see no difference except for certain pathological cases …

Depending on the needs of your parameters, you might want to spend some time understanding the difference between

C:>cmd /c TestHarness.cmd …
and
C:>cmd /s /c TestHarness.cmd …

/s was built to cover for cases where you want to cmd /c a compound command. In your situation you’d probably do better to create a cmd file to execute the compound. Note that switch order IS significant. /c (or /k) MUST be the final switch in the cmd call string. So /s must come before /c or /k.

Happy cmd-ing.

I guess I should preview; Terminus Est & douglips beat me to it.

For invoking features that are a true part of cmd, like echo, you have to invokle cmd. likewise if you’re trying to run a cmd file.

But in general I agree with the others that you should not invoke cmd unless you need to. Better to have perl call “myprog.exe” than “cmd.exe / c myprog.exe” or “cscript.exe myscript.js” versus “cmd.exe /c cscript.exe myscript.js”