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

Hello,
  I'm having some trouble with a perl script I'm writing.

when I try to execute something on the command line, it
just plain *doesn't work* i've used system & backticks (`).
No luck, when I use (`) i get no output either...

the command is:
system("/sbin/mkfs -t xfs $device"); if (!?) { print "Failed! - $?\n"; }
Failed! 13 It's that simple. I'm using system in other parts of this script and it works fine. I can even verify the system call is working, by creating a wrapper script. like so: (make_fs.pl) -------------------------------------------------------
#!/usr/bin/perl -w my $device = $ARGV[0]; print "I GOT $device !!\n"; system("/sbin/mkfs -t xfs $device"); exit($?);
-------------------------------------------------------- (in the main script) --------------------------------------------------------
#system("/sbin/mkfs -t xfs $device"); system("./make_fs.pl $device"); if (!?) { print "Failed! - $?\n"; }
I GOT /dev/exampledevice0 Failed - 13 -------------------------------------------------------- Same, exit code, and the command never ran. the reason I know this is because. if, on the command line, I run that exact same command: # /sbin/mkfs -t xfs /dev/exampledevice0 the program formats it, if it had already been formatted it would ask for me to do a --force. So this is the first time it's been formatted. the script _is_ running as root. and when I print the $! output, it just says "illegal seek". now, if I use backticks (`) instead, this is what happens:
#system("/sbin/mkfs -t xfs $device"); #system("./make_fs.pl $device"); print `/sbin/mkfs -t xfs $device`; if (!?) { print "Failed! - $?\n"; }
Failed! - 13 (no output from the first print) I have been coding in perl for over 2 years and never had this problem before. Any help GREATLY appreciated! - Nick

Replies are listed 'Best First'.
Re: calling an external program, from within a perl script
by trantor (Chaplain) on Aug 09, 2001 at 20:50 UTC

    I assume you mean if (!$?) and not if (!?). Anyway.

    From perldoc perlvar:

    $? The status returned by the last pipe close, backtick (``) command, or system() operator. Note that this is the status word returned by the wait() system call (or else is made up to look like it). Thus, the exit value of the subprocess is actually ($? >> 8), and $? & 127 gives which signal, if any, the process died from, and $? & 128 reports whether there was a core dump. (Mnemonic: similar to sh and ksh.)

    In other words, your process terminates with an exit status of zero (which should be correct), dying from signal 13, which happens to be SIGPIPE.

    Enough hints? :-)

    -- TMTOWTDI

      Nick,
      Try a variation of the following.
      system "U:\\foo\\bar\\FILENAME $input /x+ /y+ /z >$output";
      I've used something like this before where the FILENAME was an executable and the executable had some switches for various types of output. It worked on a win32 system. Have fun!
      Ok, this explains the error level. However, it doesn't 
      explain the fact that the command doesn't work from this 
      perl script. However, it does work from the cmnd 
      line, and also from a little 3 liner (in the examples 
      above).
      
      So I know the system call is working, because it can call 
      the 3 line perl script. I know the command 'mkfs' is 
      working, because I can run the 3 liner, and the command 
      executes.
      
      when I run the 'mkfs' command from the large perl script,
       even though ($? >> 8) may return a 0 exit code, the device 
      is not created, because there is not XFS filesystem on the
      device when I check after running it.
      
      Also, if I grab the output with backticks, there is none.
       (and this is a verbose command, so there should be several 
      lines of output when generating the XFS Filesystem).
      
      Any thoughts?
      
      - Nick
      

        Let's see...

        • SIGPIPE is sent to the process when it tries to write to a pipe with no connected readers
        • mkfs -t fstype is just a wrapper that spawns the appropriate mkfs.fstype
        • It works fine on the command line
        I tried the script myself using mkfs -t ext2 /dev/fd0 and it worked fine. Messages were output to STDERR but no problem whatsoever. I don't have xfs so I can't test it under your conditions, but perhaps you can test the script under mine and see what happens.

        If it works fine, my guess is that mkfs.xfs expects some kind of interaction with the user (you mentioned a condition where --force was necessary) and it dies because it's not connected to a terminal.

        If it still does not work, experiment:

        • Is the error code still the same?
        • What happens using another device?
        • What happens using an illegal device on purpose?
        • What happens using anothe filesystem type?
        • And with an illegal filesystem type?
        • What happens with another command?
        • Does a shell line like echo `your command` work?
        And so on. By observing (hopefully) different behaviours, it should be possible to determine what triggers the problem. Hope this helps!

        -- TMTOWTDI

Re: calling an external program, from within a perl script
by VSarkiss (Monsignor) on Aug 09, 2001 at 20:44 UTC

    There must be a typo in there. This just doesn't parse: if (!?) { print "Failed! - $?\n"; }All that produces is "Search pattern not terminated".

    Maybe you could copy-and-paste again? Probably the typo'ed string is the problem.

Re: calling an external program, from within a perl script
by mischief (Hermit) on Aug 09, 2001 at 21:46 UTC

    Have you tried passing the arguments to mkfs like this:

    system('/sbin/mkfs', '-t', 'xfs', $device);

    ?

      yes, i tried putting the args for system in an array like that, but this makes no difference.
       
      - Nick