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

Hi, I'm writing some perl CGI scripts on a solaris 2.6 platform. I've noticed that perl (v 5.005_02) has a nasty habit of assuming that shell commands are done, whether they are or not. This has been true whether I use system("....") or `command...`. How much of this is to blame on perl vs. Solaris? Is there a better way to issue shell commands? For now, I'm having to add checks every step of the way to make sure that a shell command is really done. It's been a QA nightmare for me, with programs that behave quite differently depending on the time of day.

Replies are listed 'Best First'.
Re: Frustrated with system calls
by lemming (Priest) on Feb 14, 2001 at 00:43 UTC
    Are you checking the output of your commands?
    What changes during that day that causes a command to fail at one time, but work at other times?
    Update to clarify:
    From system:

    The return value is the exit status of the program as returned by the wait call. To get the actual exit value divide by 256. See also exec. This is not what you want to use to capture the output from a command, for that you should use merely backticks or qx//, as described in `STRING` in the perlop manpage. Return value of -1 indicates a failure to start the program (inspect $! for the reason).

Re: Frustrated with system calls
by goldclaw (Scribe) on Feb 14, 2001 at 00:45 UTC
    Perl doesn't asume anything, it waits around until the commands exit. Unless of cource you run them in the background(end the command with &), in which case perl asume that they can take care of themselves and move on

    Du you have any examples of these commands that perl doesnt wait for? Might be easier to explain to you what's going on with a good example...

    goldclaw

      Well, in theory, it's supposed to wait. I do not use &. I have found that:
    • - it does not wait for "cp" commands to finish. When I say system("cp a b") or `cp a b`, it will go to the next command while b is still at file size 0.
    • - it does not wait for binary executables to finish. If I say system("executable > abc") or `executable > abc`, it will proceed to the next line while abc is still growing.

      Could any of this behavior somehow be caused by the CGI module?


        Two basic rules that are generally true when dealing with commands is to always check the return values and to keep as much within perl as you can. Try using the File::Copy module (not certain if it comes with 5.005), it should make things easier as it will error to screen something useful (not always true of system commands).

        For a command like cp perl will wait in my experience. If you are worried about this you can pause your script for a second (or whatever time it usually takes plus some seconds for good measure) to make certain the shell command is finished. But also check the return value (with the system call this is relatively easy), just in case.

        HTH,
        jynx

        Both of these could be caused by the OS, at least if the files b and abc are on disks mounted through nfs. The programs are done, but the data hasn't been written to disk yet. Do you know if those files are on an nfs-mounted disk? If so, try putting them on a local disk, that might help.

        GoldClaw

Re: Frustrated with system calls
by MadraghRua (Vicar) on Feb 14, 2001 at 02:24 UTC
    Have you tried something like:
    $system = system("cp a b"); if ($system > 0) { print("Error occured: $signal\n"); } else { ...do whatever comes next... }

    Unix returns an exit value when it completes a command so you should be able to assign that value to $signal and test it for its value. Look at the man page for cp for some ideas. Good luck.

    MadraghRua
    yet another biologist hacking perl....

Re: Frustrated with system calls
by dws (Chancellor) on Feb 14, 2001 at 00:50 UTC
    You've not given us much to go on. You would help us help you if you could post a short example script of a shell command that you see failing.

    (Update: Moot. More info provided above.)