How can I run an external command and capture its output in Perl?

后端 未结 4 1889
南旧
南旧 2020-12-06 00:34

I\'m new to Perl and want to know of a way to run an external command (call it prg) in the following scenarios:

  1. Run prg, get its
4条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-06 00:41

    Beware about the answer of Eugene (can't comment on his answer), just above, that the syntax to exchange SDTOUT and STDERR is valid on Unixes (Unixen-like shells such as ksh, or bash I guess) but not under Windows CMD (error: 3>& was unexpected at this time.).

    The appropriate syntax under Windows CMD and Perl on Windows is:

    perl -e "$r=qx{nslookup 255.255.255.255 2>&1 1>&3 3>&2};
    

    Note that the command:

    nslookup 255.255.255.255
    

    will produce (something like) on STDOUT:

    Server:  mymodem.lan
    Address:  fd37:c01e:a880::1
    

    and on STDERR:

    *** mymodem.lan can't find 255.255.255.255: Non-existent domain
    

    You can test that this syntax works with the following CMD/Perl syntax:

    First:

    perl -e "$r=qx{nslookup 255.255.255.255 2>&1 1>&3 3>&2}; $r=~s/[\n\r]//eg; print qq{on STDOUT qx result=[$r]};"
    

    you get: Server: mymodem.lan Address: fd37:c01e:a880::1 on STDOUT qx result=[*** mymodem.lan can't find 255.255.255.255: Non-existent domain]

    Then

    perl -e "$r=qx{nslookup 255.255.255.255 2>&1 1>&3 3>&2}; $r=~s/[\n\r]//eg; print STDOUT qq{on STDOUT qx result=[$r]};" 2>&1 1>NUL:
    

    you get: Server: mymodem.lan Address: fd37:c01e:a880::1

    QED [fr:CQFD]

    Note that it is not possible to get BOTH stderr and stdout as returned string for a qx or backticks command. If you know for sure that the err text returned by your spawned command is of length N lines, you can still redirect STDERR to STDOUT like describe by Eugene and others but capture your qx returned text in an array instead of as scalar string. The STDERR flow will be returned into the array before the STDOUT so that the N first lines of your array are the SDTERR lines. Like:

    @r=qx{nslookup 255.255.255.255 2>&1};
    $r[0] is "*** mymodem.lan can't find 255.255.255.255: Non-existent domain"
    

    But of course you must be sure that there is an err text on STDERR and of strictly N lines (stored in @r[0..N-1]). If not, the only solution is using temp files as described above.

提交回复
热议问题