http://qs321.pair.com?node_id=570586

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

Hi, I am working with Win32 and I want to execute a external DOS program. From the Perl manual, I found that the system command needs to be used. For example, if I have to get the files in a particular folder listed, I used a code

$cmd = system("dir"); print $cmd;

On executing the code, it returns a value '65280' on the screen. I don't know where this came from. Can anyone tell me how to run a external command and get the desired output on the screen. And also, if possible, what is this 65280??

Replies are listed 'Best First'.
Re: Executing a external command
by shmem (Chancellor) on Aug 31, 2006 at 12:05 UTC
    In your code, $cmd is the return value of your system call.

    From system:

    The return value is the exit status of the program as returned by the wait call. To get the actual exit value, shift right by eight.
    so if '65280' is returned, the actual value is 255 (== 65280 >> 8). Check your OS's documentation about that error number.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Executing a external command
by borisz (Canon) on Aug 31, 2006 at 11:57 UTC
Re: Executing a external command
by cdarke (Prior) on Aug 31, 2006 at 12:07 UTC
    For historical (UNIX) reasons the exit code is shifted, to get the correct return code shift right by 8 bits:
    print $cmd >> 8
    The number 65280 translates to 255, or -1 (a signed byte, honest). Most likely it cannot run the function dir.
    That should work under Windows NT/2000/XP, however you did say that you were running DOS. This might sound pedantic, but DOS is an old 16-bit operating system that used command.com, and dir was a built-in. If so you need to invoke command.com.
    However, it would be better to use Perl instead, why not:
    print join ("\n", glob('*'));

    You can get file details using stat.
Re: Executing a external command
by izut (Chaplain) on Aug 31, 2006 at 11:58 UTC

    I don't think dir is an external command, but a builtin cmd command. If you want to list files from directories, I advise you to use File::Find or File::Find::Rule.

    Igor 'izut' Sutton
    your code, your rules.

Re: Executing a external command
by mantra2006 (Hermit) on Aug 31, 2006 at 12:20 UTC
    Hello
    When I run your command in my system (Win2K) it gave a directory
    list and $cmd as 0.
    Coming to your question when you execute a command using system
    it returns a status of the execution of the command
    for eg. system command is success then it returns "0"
    or otherwise another number each number has its own meaning
    in your case 65280 means the system command couldn't succeed in running...which Operating System
    are you using to run this script?

    Sridhar
    Thanks & Regards Sridhar
Re: Executing a external command
by ww (Archbishop) on Aug 31, 2006 at 15:04 UTC

    Interestingly... on W2k with AS 5.8.6

    C:\foo\>perl -e "print `dir;" Can't find string terminator "`" anywhere before EOF at -e line 1.

        ...and yes, that is a backtic before dir.
    Did it need to be escaped? Or am I truly deep into Altz-a-whatchamajig?

    UPDATE See reneeb's shot of brainpower, immediately below.

    However ...

    C:\foo\>perl -e "system dir;" <snip ...> Directory of C:\foo\ 08/31/2006 10:06a <DIR> . 08/31/2006 10:06a <DIR> .. 11/21/2003 02:49p <DIR> .c-- 11/21/2003 02:49p <DIR> .c# <snipped - no further interest here ... >

    ...and...

    C:\foo\>perl -e "$cmd=system(dir);print $cmd;" <snip ...> Directory of C:\foo\ 08/31/2006 10:06a <DIR> . 08/31/2006 10:06a <DIR> .. 11/21/2003 02:49p <DIR> .c-- 11/21/2003 02:49p <DIR> .c# <snipped> 3 File(s) 2,731 bytes 9 Dir(s) 67,502,247,936 bytes free 0 <=== There is the UNshifted system status/return code referenced abo +ve.... C:\foo\>
      There is a backtick after dir missing.
        Thank you, reneeb, both for the knowledgable reply, and for the resultant lesson...

        "Resultant Lesson" you say?

        Well, I was busy drafting a scathing [and undoubtedly -- ;-) -- brilliant ] diatribe on the difference between quotes and operators -- en route to exposing my misunderstanding [ ignorance! ] here, when I needed to check perlop for a precise definition on a minor point in my argument, only to there discover that, in fact, quotes are (sometimes, in effect) operators ( think "interpolation" ).

        In perlop | Regexp Quote-Like Operators | qx/STRING/ one will find (as I did) a subhead: `STRING` and there discover that the examples make the requirement for a closing backtick clear. (Fact is, I have not yet found where the documentation makes that explicit, but other authorities offer statements like "Remember, the string (system command) to be executed and its arguments must be followed by a(nother) backtick."

        Bottom line?

        C:\foo>perl -e "print `dir`;" <snip> Directory of C:\foo 08/31/2006 10:06a <DIR> . 08/31/2006 10:06a <DIR> .. 11/21/2003 02:49p <DIR> .c-- 11/21/2003 02:49p <DIR> .c# <snip> ...

        reneeb's Re^2: Executing a external command is correct. Thank you again.