Get system command output: Difference between revisions

From Rosetta Code
Content added Content deleted
(added Perl 6 section)
m (→‎{{Header|Perl 6}}: add {{out}})
Line 132: Line 132:
=={{Header|Perl 6}}==
=={{Header|Perl 6}}==
<lang perl6>say qx[dir]</lang>
<lang perl6>say qx[dir]</lang>
{{out}}
<pre>Find_URI_in_text.p6 History_variables.p6 K-d_tree.pl
<pre>Find_URI_in_text.p6 History_variables.p6 K-d_tree.pl
Fractran.pl History_variables.pl XML_Input.p6</pre>
Fractran.pl History_variables.pl XML_Input.p6</pre>

Revision as of 01:58, 3 June 2014

Get system command output is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Execute a system command and get its output into the program. The output may be stored in any kind of collection (array, list, etc.). For some languages this is a non-trivial task.

AWK

<lang AWK>

  1. syntax: GAWK -f GET_SYSTEM_COMMAND_OUTPUT.AWK

BEGIN {

   cmd = "GAWK 1 FILENAME"
   method1()
   method2()
   cmd = "TYPE FILENAME"
   method1()
   method2()
   exit(0)

} function method1( data,dev,rec ) { # use system() to run command

   printf("%s\n",cmd)
   dev = "C:\\TEMP\\TMP.TMP"
   system(cmd ">" dev)
   close(dev)
   while (getline rec <dev > 0) {
     data = data rec "\n"
   }
   print(data)

} function method2( data,rec) { # use "|" to implicitly run command

   printf("%s\n",cmd)
   while ((cmd | getline rec) > 0) {
     data = data rec "\n"
   }
   close(cmd)
   print(data)

} </lang>

input FILENAME consists of three, one character records

output:

GAWK 1 FILENAME
a
b
c

GAWK 1 FILENAME
a
b
c

TYPE FILENAME
a
b
c

TYPE FILENAME
a
b
c

Go

<lang go>package main

import (

 "fmt"
 "log"
 "os/exec"

)

func main() {

 output, err := exec.Command("ls", "-l").CombinedOutput()
 if err != nil {
   log.Fatal(err)
 }
 fmt.Print(string(output))

}</lang>

J

We will box the result of uname -imp on a linux system, to show that we have captured the command output in J:

<lang J> require 'task'

  <shell 'uname -imp'

┌─────────────────────┐ │x86_64 x86_64 x86_64 │ └─────────────────────┘</lang>

Caution: I have sometimes seen some versions of linux refuse to execute subshells after a few hundred thousand shell commands (the exec system call fails). I've not found any satisfying documentation on why this happens, but I strongly suspect kernel memory fragmentation (the examples where this happened were also using a lot of memory to accumulate results and it happened much more frequently an machines with little memory than on machines with more memory). Exiting J and starting a new process has cleared it up when it has happened. Anyways, I usually prefer to do that kind of processing before J starts, just to be safe.

(I've seen other problems on windows and osx - I am only singling out linux here because it is the most convenient for command line and system command use.)

ooRexx

<lang ooRexx>/* Execute a system command and retrieve its output into a stem. */

 trace normal

/* Make the default values for the stem null strings. */

 text. = 

/* Issue the system command. "address command" is optional.) */

 address command 'ls -l | rxqueue'

/* Remember the return code from the command. */

 ls_rc = rc

/* Remember the number of lines created by the command. */

 text.0 = queued()

/* Fetch each line into a stem variable. */

 do t = 1 to text.0
   parse pull text.t
 end

/* Output each line in reverse order. */

 do t = text.0 to 1 by -1
   say text.t
 end

/* Exit with the system command's return code. */ exit ls_rc</lang>

Perl

Uses the qx{} construct (which is a synonym for backticks, e.g. `command`) to execute a given command and redirect its output. A standard example, capturing only STDOUT: <lang perl>my @directories = grep { -d $_ } `ls`; foreach @directories { chomp;

  1. Operator on directories

}</lang> Perl also honors shell redirections: <lang perl>my $command = shift or die "No command supplied\n"; my @output_and_errors = qx/$command 2>&1/ or die "Couldn't execute command\n";</lang> qx// is implemented internally with the built-in function readpipe, which can be invoked directly as readpipe EXPR (where EXPR is some command) and assigned to scalars or lists just like qx/command/ or `command`.

Perl 6

<lang perl6>say qx[dir]</lang>

Output:
Find_URI_in_text.p6  History_variables.p6  K-d_tree.pl
Fractran.pl	     History_variables.pl  XML_Input.p6

Python

<lang python>>>> import subprocess >>> returned_text = subprocess.check_output("dir", shell=True, universal_newlines=True) >>> type(returned_text) <class 'str'> >>> print(returned_text)

Volume in drive C is Windows
Volume Serial Number is 44X7-73CE
Directory of C:\Python33

04/07/2013 06:40 <DIR> . 04/07/2013 06:40 <DIR> .. 27/05/2013 07:10 <DIR> DLLs 27/05/2013 07:10 <DIR> Doc 27/05/2013 07:10 <DIR> include 27/05/2013 07:10 <DIR> Lib 27/05/2013 07:10 <DIR> libs 16/05/2013 00:15 33,326 LICENSE.txt 15/05/2013 22:49 214,554 NEWS.txt 16/05/2013 00:03 26,624 python.exe 16/05/2013 00:03 27,136 pythonw.exe 15/05/2013 22:49 6,701 README.txt 27/05/2013 07:10 <DIR> tcl 27/05/2013 07:10 <DIR> Tools 16/05/2013 00:02 43,008 w9xpopen.exe

              6 File(s)        351,349 bytes
              9 Dir(s)  46,326,947,840 bytes free

>>> # Ref: https://docs.python.org/3/library/subprocess.html</lang>

REXX

Works with: Regina

<lang rexx>/*REXX program does a system command and shows results (from an array). */ trace off /*suppress REXX err msg for fails*/ @.=0 /*default in case ADDRESS fails. */ address system arg(1) with output stem @. /*issue the command & parms.*/ if rc\==0 then say copies('─',40) 'return code' rc "from: " arg(1)

                                      /* [↑]  tell if an error occurred*/
          do out=1  for @.0           /*display the output from command*/
          say strip(@.out,'T')        /*display one line at a time.    */
          end   /*out*/               /* [↑]  displays all the output. */

exit 0 /*stick a fork in it, we're done.*/</lang> output from the executed command:   dir g:sub*.2*   under Windows/XP:

 Volume in drive G is -----G-----
 Volume Serial Number is 6826-1B4B

 Directory of G:\

05/22/2012  08:27                30 SUBSET.2
05/24/2012  03:55         2,117,571 SUBSET.20
05/24/2012  03:55         1,132,068 SUBSET.21
05/24/2012  09:56           522,155 SUBSET.22
05/24/2012  09:56           193,293 SUBSET.23
05/24/2012  09:56            71,931 SUBSET.24
05/24/2012  09:56            15,995 SUBSET.25
05/24/2012  09:56             3,188 SUBSET.26
05/24/2012  09:56               471 SUBSET.27
               9 File(s)      4,056,702 bytes
               0 Dir(s)  18,252,660,736 bytes free

Tcl

The exec makes this straight-forward for most commands. <lang tcl>set data [exec ls -l] puts "read [string length $data] bytes and [llength [split $data \n]] lines"</lang> There are a few exceptions, such as the DIR command on Windows, where they need to be run slightly differently due to being system shell builtins rather than executables. In that case, the auto_execok standard library command is used to look up how to run the command (strictly it can be used for any command — it will do path resolution, etc. — but is only necessary for system builtins). <lang tcl>set data [exec {*}[auto_execok DIR]]</lang> By default, Tcl will use the system encoding (as reported by encoding system) to understand the output byte-stream as characters, and will auto-convert all the various types of newline terminators into U+00000A characters. Control over this is possible by launching the subprocess as a pipe, configuring the pipe, and then reading the pipe in its entirety. <lang tcl># This syntax is pretty ugly, alas set pipe [open |[list ls -l] "r"] fconfigure $pipe -encoding iso8859-1 -translation lf set data [read $pipe] close $pipe</lang> This is usually not necessary except when dealing with binary data output.