cormanaz has asked for the wisdom of the Perl Monks concerning the following question:

Good morning Monks. I am trying to get a perl script to run a batch file in a windows XP directory like so:
#!/usr/bin/perl -w use strict; my $prog = "c:\\program files\\agent\\agent.bat"; system($prog);
When I run this I get an error that says: Can't spawn "cmd.exe": No such file or directory at c:\projects\runbatch.pl line 4.

Well there IS such a file or directory, and the file has been tested and works when run from its directory. (I need to use the batch file because the program it's running assumes /program files/agent is the working dir).

I've googled around on this problem, and the hits mostly have to do with permissions on unix systems or win servers, or PHP. The few things about it on super search have been of little help.

Anyone know what I'm doing wrong?

TIA.....Steve

Replies are listed 'Best First'.
Re: system command can't spawn cmd.exe
by radiantmatrix (Parson) on Jan 12, 2005 at 14:54 UTC

    Using pathnames in Windows is disturbingly annoying. While on its face, your code appears to have no issues, there could be any number of problems. For example, if Perl is installed with restricted priviledges, it may not have rights to invoke your shell (cmd.exe on Windows 2k/XP). However, if I were a betting man, I'd bet that something odd about your path spec is tripping things up.

    The solution is one of two things. First, you could use File::Spec to build your path, thus basically eliminating the potential for path-related problems. That's usually a good idea even if you aren't having problems.

    Or, because you say I need to use the batch file because the program it's running assumes /program files/agent is the working dir, you could simply use chdir. Like so:

    my $real_prog = 'agent.exe'; my $path = File::Spec->canonpath('c:\program files\agent'); chdir ($path); system ($real_prog) if (-f $real_prog);

    radiantmatrix
    require General::Disclaimer;
    s//2fde04abe76c036c9074586c1/; while(m/(.)/g){print substr(' ,JPacehklnorstu',hex($1),1)}

Re: system command can't spawn cmd.exe
by dbwiz (Curate) on Jan 12, 2005 at 14:08 UTC

    Are you sure that your file is really there?

    Writing Windows path names correctly can be tricky sometimes. Try this one:

    #!/usr/bin/perl -w use strict; my $prog = "c:\\program files\\agent\\agent.bat"; if (-f $prog) # does it exist? { system("cmd.exe", "/C", $prog); } else # if not, let's see its name after escaping "\"s { warn "batch file ($prog) not found!\n"; }
      I get the same result: Can't spawn "cmd.exe": No such file or directory. This makes me wonder if perl has the right path for cmd.exe. But then if I put a .bat file in the same directory as my perl script, it runs just fine! Very strange.

      And as for the other suggestion about running as admin, my account is not literally admin but it is a member of the admin group and I have full admin privileges.

      Steve

Re: system command can't spawn cmd.exe
by YetAnotherDave (Beadle) on Jan 12, 2005 at 14:35 UTC
    It sounds to my like the issue might be in your %PATH%, but cmd.exe really should be in C:\WINNT\system32\, which ought to be in your PATH. Try 'set PATH' to check this.

    >> I need to use the batch file because the program it's
    >> running assumes /program files/agent is the working dir

    so if you added a 'chdir' call to your perl you could avoid the batch file? I'd probably try to do that, if it was my code...
      I'd recommend adding a chdir to the script. BAT files can be annoying when you have to call them from Perl scripts. Also, it may not necessarily be the BAT file in and of itself, but if its calling an executable thats assuming a certain directory, then things get trickier. The whole process is annoying and requires patience to get it working correctly.
Re: system command can't spawn cmd.exe
by hokie (Monk) on Jan 12, 2005 at 14:54 UTC
    I've had similar problems before, you might want to try using the File:Spec module. So:

    #!/usr/bin/perl -w use strict; use File::Spec; my $prog = File::Spec->catfile('program files', 'agent', 'agent.bat'); system($prog);

    Also perl generally doesn't like paths that have spaces so you might want to try quoting the path and then running it again.

    -Hokie
    all code is untested

Re: system command can't spawn cmd.exe
by ikegami (Patriarch) on Jan 12, 2005 at 15:04 UTC
    Please read the answers given to 392416, as they discuss the same problem. In short, Perl ignores COMSPEC and searches for CMD.EXE in the PATH. Is it in yours?
Re: system command can't spawn cmd.exe
by holli (Abbot) on Jan 12, 2005 at 13:55 UTC
    All I can say is that the code is running fine for me. I am working with admin rights. You should try to login as administrator and see what happens.

    Update
    ZlR comment is reasonable, the space could be the problem, so you could escape the path like so:
    #!/usr/bin/perl -w use strict; my $prog = "\"c:\\program files\\agent\\agent.bat\""; system($prog);
      Hi holli ,

      I don't think this will work, in fact i just tested and it doesn't work !
      Protecting the command itself with quotes doesn't protects from the space, at least in my shell.

      zlr

        I've found protecting it with single quotes instead of double quotes often works. Something like:

        $file=File::Spec->catfile('c:','path',with spaces',to','file'); $file="\'$file\'";
Re: system command can't spawn cmd.exe
by bart (Canon) on Jan 12, 2005 at 15:50 UTC
    Your problem may be something other than you think it is. I notice your path has a space in it... so cmd.exe searches for a file 'c:\program', which doesn't exist.

    Try putting quotes inside the string, around the full path.

    my $prog = "c:\\program files\\agent\\agent.bat"; system(qq("$prog"));

    The "fix everything" solution is, of course, to use a path without spaces.

      I'm not to sure that's the real problem, If it were they would get an error along the lines of 'c:\program' is not recognized as an internal or external command, operable program or batch file.

      For that matter, no matter how I've tried to mangle the path to the bat, I can't get any errors about cmd.exe, I've even emptied everything out of the Path, and all that happened then is, ... well nothing, the script runs but the bat either doesn't run or has no output, but no error. I tried to see if I could generate the error by renaming cmd.exe, but I just got a new one right away.

      update: ah here we go, forgot to turn warnings on when testing:
      With Path emptied of everything but perl, I get the same error, and just to see if I could match, I ran the script from the same directory and gave it just the name of the .bat, and it ran just fine. So i would have to agree with some of the previous posters in that it's a problem with the the Path environment variable, it apparently doesn't contain the path to cmd.exe. Though I'm not entirely certain why everything runs fine when it's passed just the batch file's name

      update: minor reformatting

      Just Another Perl Alchemist
        Yeah, I'm not convinced that $prog has anything to do with it. When tested under Win2000 Pro running Activestate's version of Perl 5.8.4, I could not duplicate the issue. Of course, since I have no idea what's in the batch file, I can't say for sure what the problem is.

        But where $prog in test.pl reads:
        my $prog = "c:\\program files\\bwb.bat"; # personal batch file for sundry tasks
        test.pl yields no errors.

        Where $prog in test.pl reads:
        my $prog = "c:\\progra~1\\bwb.bat";
        test.pl yields no errors

        /renz.

        (EDIT: Also, I am working with local admin privs.)
Re: system command can't spawn cmd.exe
by ZlR (Chaplain) on Jan 12, 2005 at 15:06 UTC
    Hello,

    I think the problem comes from the space in "Program Files".
    The comand you launch with "system" doesnt work in my cmd shell ! And the error shows it stops at the space.

    There's a lot of workarounds, there maybe is one in the windows shell itself but i cant find it.
    Along with the other solutions in this thread i would also consider Win32::Process .

    ZlR

Re: system command can't spawn cmd.exe
by kgraff (Monk) on Jan 12, 2005 at 15:13 UTC

    I haven't worked on PC scripts since NT 4.0, but at that time long file names didn't work at all, you had to use the old style DOS type ones, 8.3 and tilde characters. If this is still the case, the following path may work:

    my $prog = "c:\\Progra~1\\agent\\agent.bat";

    Kathy A. Graff
    http://kgraff.net/
Re: system command can't spawn cmd.exe
by xaldin (Initiate) on Jan 12, 2005 at 18:32 UTC
    I had same problem on a server. Basicly the path had gotten overly long. I cleared out a bunch of junk entries that didn't need to exist and it started working. I'd suggest copying your environment path variable data to something else, cut out anything possible and try again. I'd be willing to bet it works then. Be sure in the cutting out that you leave perl and window system paths intact.

      CleanPath will automatically strip out any invalid directories from your path (both for the current command shell and in the global configuration in the Registry -- though most other things won't notice these changes unless you log out or otherwise poke them to).

      It doesn't fix directories that still exist but that shouldn't be in %PATH%, though.

      - tye        

Re: system command can't spawn cmd.exe
by Anonymous Monk on Jul 23, 2011 at 23:59 UTC
    I'm running Strawberry on XP and out of the blue, with no interactions, I started getting this error on all my system calls and backtik calls. Re-installed Strawberry and everything. So the issue ended up being a duplicate path setting in my windows environment variables. There's a 'system' path and a per user path. Basically the fix is (in XP) right click on my computer -> properties -> Advanced tab -> environment variables. Copy the system PATH variable in the bottom pane to the user one in the top pane, or append it to the one in the top pane. That was my solution and had nothing to do with directory path. Though yours may be a combination of both as the path isn't enclosed in quotes. escape some quotes inside the variable and do the PATH variable thing.
      I had this issue with some perl scripts I had inherited at work (activeperl 5.6 on server 2003). It turned out to be the way the script was being called from the command line (scheduled .cmd file). e.g. c:\scripts>script.pl (resulted in the can't spawn message) however specifying perl before calling the script which is best practice anyway allowed it to work fine: c:\scripts>PERL script.pl (allows the command line call from within the perl script to work fine).
        Fixed on Windows 7, 64 bits command prompt adding the cmd.exe path in PATH like this: set PATH=%PATH%;C:\Windows\SysWOW64
Re: system command can't spawn cmd.exe
by Anonymous Monk on Jan 13, 2005 at 18:12 UTC
    I am not sure you gave us all the pieces of this puzzle. I see one error, and I would
    like to make a suggestion.
    1) As a previous reply implied, you need to back slash the space in Program Files.
    2) The line
    Can't spawn "cmd.exe": No such file or directory at c:\projects\runbatch.pl line 4.
    is stating that whatever line 4 of c:\projects\runbatch.pl is trying to get cmd.exe
    to execute is not there.

    Try this
    #!/usr/bin/perl -w
    use strict;
    my $prog = "c:\\program\ files\\agent\\agent.bat";
    if (system("$prog")) {
    print("Cannot system $prog:$!:\n");
    } else {
    print("Success\n");
    }

    If this does not work, please let us know what the said line 4 is.

      I had the same problem on WinXP with Activestate 5.8.8. I tried changing the env path (quoting all the entries with spaces), changing the path temporarily in the script by setting $ENV{PATH} and in a desperate measure putting cmd.exe in the same directory as my perl script. nothing worked. Then, I tried using system like this:

      my $ret = system "C:\\WINDOWS\\System32\\cmd.exe /C $syscall";

      where $syscall is a string you set with the program you want to call and all its arguments. Worked perfectly for me, after way too long scratching my head... Anyway, I hope it helps someone else.