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

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

Hi, i am a new member,

and as the question's title says i would like to execute a system call but instead getting the display of the command in the console i want to have a .txt file created or be able to get the output of the file created by this system call.

So i tried :

$var = `<my command> 2>&1 1>/dev/null`;

i still had the output of the command, then

open FILE, "<my command> 2>&1 1>/dev/null" or exec(); die $!;

and system("<my command> 2>&1 1>/dev/null");

i still had the output of the command in the console. I started perl a week ago and i think i am taking the wrong approach on this problem, could you please help me ?

*update* changed the question's name

I done additional research on the command i would like to run, and found out that the command write a file that i can use so the retrieving output problem is solved but i still can cancel the display of the command

Additionally as X-mas is coming I'd like to know what books or tutorials should I read about using perl to monitor and manage external process on Linux or something nice to start. Thank you.

Regards

Thank you all for your answers i now understand my mistakes

Actually, my command couldn't execute without outputting a display so I did it in a separate terminal ... The structure i used for this purpose is :

sub sigtrap() { if(defined($pid) && ! ($pid == 0)){ killfam 'TERM', ($pid); } print "\n"; exit(1) } $pid = fork(); if($pid == 0){ #print "DEBUG - I am the child pid : $$ \n"; qx/my command running in background 2>&1 1>\/dev\/null/; sleep 10; exit(0); } sleep 15; #use the command's output file to get the results

Replies are listed 'Best First'.
Re: retrieve the value of a system call in a non blocking mode
by VincentK (Beadle) on Dec 05, 2013 at 21:06 UTC

    Hi young_monk_love_perl

    Is something like this what you want?

    use strict; use warnings; system("echo test > myfile.txt");
      Shouldn't that have been something more like
      use strict; use warnings; system("echo test > myfile.txt" or die $!);
      or how would we have known it wasn't possible to open/create myfile.txt. ;)

      --Chris

      UPDATE moved misplaced paren
      #!/usr/bin/perl -Tw
      eval {
      I'm not completely useless, I can be used as a bad example.
      }
      
        "UPDATE moved misplaced paren"

        You've removed what you originally posted so I don't know what you were attempting to fix (see "How do I change/delete my post?"). Regardless, what you now have is still not correct (I assume you didn't intend or die $! to be part of the shell command).

        See the examples in the system documentation for syntax and how to check for errors. You may also find the autodie pragma of interest.

        If you are unable to test your posted solutions, please clearly indicate this.

        Also, what you've shown as corrections later in this thread are also wrong (for the same reason). [Update (Clarification of "later in this thread"): I'm referring to "Re^4: retrieve the value of a system call in a non blocking mode" which is later than the post I'm replying to but appears physically earlier on this page.]

        -- Ken

        Hi Chris, the result of

        echo test > myfile.txt") or die $!;

        is to still display the command output in the console as usual, i cannot input anything exept SIGINT or SIGTERM, the screen display is dynamic but it doesn't create lines in the console except spaces and then freeze on the last screen when I kill the program. Maybe this precisions will be helpful.

        The .txt is created but it only contains two lines of spaces.

        Yep. You're right. I should have included the 'die' on the end of that statement. Thanks :)

Re: retrieve the value of a system call in a non blocking mode
by flexvault (Monsignor) on Dec 05, 2013 at 21:10 UTC

    Welcome young_monk_love_perl,

    On *nix try this at the command prompt:

    perl -e '$v=qx/ls/;open $f,">","./file";print $f $v;'

    What this one liner does is ask the system to list the files in the current directory and save in variable '$v'; opens a file(./file); and print the contents of variable '$v' to the file. You can use an editor to view the contents of the file.

    That's a rough beginning, but Perl has so much more to offer -- so enjoy!

    Regards...Ed

    "Well done is better than well said." - Benjamin Franklin

      Hi Ed,

      I'm sorry I don't understand, should I add this line in my script or use it to execute the scrit ?

      Because I need to call this script from a other one and I don't know how to execute the line perl -e '$v=qx/ls/;open $f,">","./file";print $f $v;' this line into perl script

        young_monk_love_perl,

          I'm sorry I don't understand...

        My answer wasn't to write your code, but to help you learn to program with Perl. If you look up the 'qx' function you will find that it is a way to call the system and have the output returned to your script. If you tried perl -e '$v=qx/ls/;' you would have found that the output of the 'ls' system command did not display on your console. (One of your requirements). I then showed you how to save the results to a text file, and if you tried the code, you would learn that once you had the output of your command, you could use 'split' to create an array or with 'map' to build a hash or, or, or, ...

        Others have given you some good examples and ideas, and you should explore their suggestions as well.

        If this is a one time requirement, you may want to hire a Perl programmer ( see 'jobs.perl.org'). If this is a career opportunity for you, then this site has lots of information to help you become a better and better Perl programmer.

        Hope this helps.

        Regards...Ed

        "Well done is better than well said." - Benjamin Franklin

Re: Do not display the command result in the console (updated)
by Crackers2 (Parson) on Dec 06, 2013 at 01:43 UTC

    One issue is that your redirections are in the wrong order

    $ ( echo "out"; echo "err" >&2 ) 2>&1 1>/dev/null err $ ( echo "out"; echo "err" >&2 ) 1>/dev/null 2>&1 $

    The first one, like you have, ends up redirecting stdout to /dev/null, but stderr to the original stdout. The second one redirects stdout to /dev/null, and then stderr to the new stdout, i.e. also /dev/null

      Hi Crackers2,

      sorry about the mistake, the one in the code I'd like to run is correct, I checked. I'm correcting myself in the question. Also, the command does not output anything in the standard error output for now. So I don't understand why i still have the display.

Re: retrieve the value of a system call in a non blocking mode
by Lennotoecom (Pilgrim) on Dec 05, 2013 at 21:10 UTC
    @a = `ifconfig`;
    this sinppet does ifconfig
    stores ouput in the array
    so nothing's on the screen

    but your code
    @a = `ifconfig 2>&1 1>/dev/null`;
    does ifconfig
    redirects stderr into stdout
    redirects stdout into null
    so perl gets nothing
    but the command is executed
    something like that