Execute a system command: Difference between revisions
→{{header|Objective-C}}: added complete example (because of NSAutoreleasePool I believe it is needed) |
No edit summary |
||
Line 1: | Line 1: | ||
{{Task|Programming environment operations}} |
{{Task|Programming environment operations}} |
||
In this task, the goal is to run either the < |
In this task, the goal is to run either the <tt>ls</tt> (<tt>dir</tt> on Windows) system command, or the <tt>pause</tt> system command. |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Line 112: | Line 112: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|1.5+}} |
{{works with|Java|1.5+}} |
||
<java>import java.util.Scanner; |
<lang java>import java.util.Scanner; |
||
import java.io.*; |
import java.io.*; |
||
Line 126: | Line 126: | ||
} |
} |
||
} |
} |
||
}</ |
}</lang> |
||
{{works with|Java|1.4+}} |
{{works with|Java|1.4+}} |
||
Line 281: | Line 281: | ||
<!-- {{libheader|Cocoa}} --> |
<!-- {{libheader|Cocoa}} --> |
||
<objc>#import <Cocoa/Cocoa.h> |
<lang objc>#import <Cocoa/Cocoa.h> |
||
//works also with |
//works also with |
||
//#import <Foundation/Foundation.h> |
//#import <Foundation/Foundation.h> |
||
Line 302: | Line 302: | ||
[pool release]; |
[pool release]; |
||
return 0; |
return 0; |
||
}</ |
}</lang> |
||
Line 310: | Line 310: | ||
Just run the command: |
Just run the command: |
||
<ocaml>Sys.command "ls"</ |
<lang ocaml>Sys.command "ls"</lang> |
||
To capture the output of the command: |
To capture the output of the command: |
||
<ocaml>#load "unix.cma";; |
<lang ocaml>#load "unix.cma";; |
||
let syscall cmd = |
let syscall cmd = |
||
let inc, outc = Unix.open_process cmd in |
let inc, outc = Unix.open_process cmd in |
||
Line 325: | Line 325: | ||
let _status = Unix.close_process (inc, outc) in |
let _status = Unix.close_process (inc, outc) in |
||
Buffer.contents buf;; |
Buffer.contents buf;; |
||
let listing = syscall "ls";;</ |
let listing = syscall "ls";;</lang> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
Revision as of 15:31, 3 February 2009
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
In this task, the goal is to run either the ls (dir on Windows) system command, or the pause system command.
Ada
<Ada>
with Interfaces.C; use Interfaces.C; procedure Execute_System is function Sys (Arg : Char_Array) return Integer; pragma Import(C, Sys, "system"); Ret_Val : Integer; begin Ret_Val := Sys(To_C("ls")); end Execute_System;
</Ada>
AppleScript
do shell script "ls" without altering line endings
C
Platform: BSD
#include <stdlib.h> int main() { system("ls"); }
C++
system("pause");
C#
using System; class Execute { static void Main() { System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.EnableRaisingEvents=false; proc.StartInfo.FileName="ls"; proc.Start(); } }
dc
! ls
E
def ls := makeCommand("ls") ls("-l")
def [results, _, _] := ls.exec(["-l"]) when (results) -> { def [exitCode, out, err] := results print(out) } catch problem { print(`failed to execute ls: $problem`) }
Erlang
os:cmd("ls").
Forth
s" ls" system
Haskell
import System.Cmd main = system "ls"
IDL
$ls
Will execute "ls" with output to the screen.
spawn,"ls",result
will execute it and store the result in the string array "result".
spawn,"ls",unit=unit
will execute it asynchronously and direct any output from it into the LUN "unit" from whence it can be read at any (later) time.
Io
SystemCall with("ls") run
J
The system command interface in J is provided by the standard "task" script:
load'task' NB. Execute a command and wait for it to complete shell 'dir' NB. Execute a command but don't wait for it to complete fork 'notepad' NB. Execute a command and capture its stdout stdout =: shell 'dir' NB. Execute a command, provide it with stdin, NB. and capture its stdout stdin =: 'blahblahblah' stdout =: stdin spawn 'grep blah'
Java
<lang java>import java.util.Scanner; import java.io.*;
public class Program {
public static void main(String[] args) { try { Process p = Runtime.getRuntime().exec("cmd /C dir"); Scanner sc = new Scanner(p.getInputStream()); while (sc.hasNext()) System.out.println(sc.nextLine()); } catch (IOException e) { System.out.println(e.getMessage()); } }
}</lang>
There are two ways to run system commands. The simple way, which will hang the JVM (I would be interested in some kind of reason). -- this happens because the the inputStream buffer fills up and blocks until it gets read. Moving your .waitFor after reading the InputStream would fix your issue (as long as your error stream doesn't fill up)
import java.io.IOException; import java.io.InputStream; public class MainEntry { public static void main(String[] args) { executeCmd("ls -oa"); } private static void executeCmd(String string) { InputStream pipedOut = null; try { Process aProcess = Runtime.getRuntime().exec(string); aProcess.waitFor(); pipedOut = aProcess.getInputStream(); byte buffer[] = new byte[2048]; int read = pipedOut.read(buffer); // Replace following code with your intends processing tools while(read >= 0) { System.out.write(buffer, 0, read); read = pipedOut.read(buffer); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException ie) { ie.printStackTrace(); } finally { if(pipedOut != null) { try { pipedOut.close(); } catch (IOException e) { } } } } }
And the right way, which uses threading to read the InputStream given by the process.
import java.io.IOException; import java.io.InputStream; public class MainEntry { public static void main(String[] args) { // the command to execute executeCmd("ls -oa"); } private static void executeCmd(String string) { InputStream pipedOut = null; try { Process aProcess = Runtime.getRuntime().exec(string); // These two thread shall stop by themself when the process end Thread pipeThread = new Thread(new StreamGobber(aProcess.getInputStream())); Thread errorThread = new Thread(new StreamGobber(aProcess.getErrorStream())); pipeThread.start(); errorThread.start(); aProcess.waitFor(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException ie) { ie.printStackTrace(); } } } //Replace the following thread with your intends reader class StreamGobber implements Runnable { private InputStream Pipe; public StreamGobber(InputStream pipe) { if(pipe == null) { throw new NullPointerException("bad pipe"); } Pipe = pipe; } public void run() { try { byte buffer[] = new byte[2048]; int read = Pipe.read(buffer); while(read >= 0) { System.out.write(buffer, 0, read); read = Pipe.read(buffer); } } catch (IOException e) { e.printStackTrace(); } finally { if(Pipe != null) { try { Pipe.close(); } catch (IOException e) { } } } } }
Logo
The lines of output of the SHELL command are returned as a list.
print first butfirst shell [ls -a] ; ..
MAXScript
dosCommand "pause"
Make
make can use system command in either definition of variables or in the targets
in definition
contents=$(shell cat foo) curdir=`pwd`
in target
mytarget: cat foo | grep mytext
Objective-C
NSTask runs an external process with explicit path and arguments.
void runls() { [[NSTask launchedTaskWithLaunchPath:@"/bin/ls" arguments:[NSArray array]] waitUntilExit]; }
If you need to run a system command, invoke the shell:
void runSystemCommand(NSString *cmd) { [[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", cmd, nil]] waitUntilExit]; }
Complete usage example:
<lang objc>#import <Cocoa/Cocoa.h>
//works also with
//#import <Foundation/Foundation.h>
//i.e. outside Cocoa (e.g. with GNUstep)
void runSystemCommand(NSString *cmd) {
[[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", cmd, nil]] waitUntilExit];
}
int main(int argc, const char **argv) {
NSAutoreleasePool *pool; pool = [NSAutoreleasePool new]; runSystemCommand(@"ls"); [pool release]; return 0;
}</lang>
Or use the C method above.
OCaml
Just run the command:
<lang ocaml>Sys.command "ls"</lang>
To capture the output of the command:
<lang ocaml>#load "unix.cma";; let syscall cmd =
let inc, outc = Unix.open_process cmd in let buf = Buffer.create 16 in (try while true do Buffer.add_channel buf inc 1 done with End_of_file -> ()); let _status = Unix.close_process (inc, outc) in Buffer.contents buf;;
let listing = syscall "ls";;</lang>
Perl
my @results = qx(ls); # runs command and returns its STDOUT as a string my @results = `ls`; # ditto, alternative syntax system "ls"; # runs command and returns its exit status; its STDOUT gets output to our STDOUT print `ls`; #The same, but with back quotes exec "ls"; # replace current process with another
Also see: http://perldoc.perl.org/perlipc.html#Using-open()-for-IPC http://perldoc.perl.org/IPC/Open3.html
PHP
The first line execute the command and the second line display the output:
@exec($command,$output); echo nl2br($output);
Note:The '@' is here to prevent error messages to be displayed, 'nl2br' translate '\n' chars to 'br' in HTML.
Pop11
The sysobey function runs commands using a shell:
sysobey('ls');
Python
import os code = os.system('ls') # Just execute the command, return a success/fail code output = os.popen('ls').read() # If you want to get the output data
or
import subprocess output = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE).stdout print output.read()
Note: The latter is the preferred method for calling external processes, although cumbersome, it gives you finer control over the process.
or
import commands stat, out = commands.getstatusoutput('ls') if not stat: print out
Raven
Back tick string is auto executed:
`ls -la` as listing
Or specifically on any string:
'ls -la' shell as listing
Ruby
string = `ls`
Tcl
puts [exec ls]
This page uses "ls" as the primary example. For what it's worth, Tcl has built-in primitives for retrieving lists of files so one would rarely ever directly exec an ls command.
It is also possible to execute a system command by "open"ing it through a pipe from whence any output of the command can be read at any (later) time. For example:
set io [open "|ls" r]
would execute "ls" and pipe the result into the unit "io". From there one could receive it either line by line like this:
set nextline [gets $io]
or read the whole shebang in a fell swoop:
set lsoutput [read $io]
If the command is opened "rw", it is even possible to send it user input through the same handle.
Toka
needs shell " ls" system
UNIX Shell
UNIX shells are designed to run system commands as a default operation.
ls
If one wants to capture the command's standard output:
CAPTUREDOUTPUT=$(ls)
In C-Shell this can be achieved by
set MYCMDOUTPUT = `ls` echo $MYCMDOUTPUT
Where as in Korn Shell it becomes:
MYCMDOUTPUT=`ls` echo $MYCMDOUTPUT
Note: in these last cases, C-Shell and Korn Shell, these are "backticks" rather than quotes or apostrophes. These "backticks" can also be used in Bourne compatible shells, though the $(...) form is preferred when discussing such things in e-mail, on USENET, or in other online forums (such as this wiki). Also the $(...) form of command substitution is nestable.
If one wishes to replace the shell process with some other command (chain into some command with no return) one can use the exec shell built-in command in any of the common UNIX shells (C-Shell, and all of the Bourne-compatible shells).
exec ls
Visual Basic
Shelling out a sub task in Visual Basic is rather a pain if you need to wait for the task to complete, which is probably the usual case. But it is possible. <VB>Attribute VB_Name = "mdlShellAndWait" Option Explicit
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Private Const STATUS_PENDING = &H103& Private Const PROCESS_QUERY_INFORMATION = &H400
' ' Little function go get exit code given processId ' Function ProcessIsRunning( processId as Long ) as Boolean
Dim exitCode as Long Call GetExitCodeProcess(lProcessId, exitCode) ProcessIsRunning = (exitCode = STATUS_PENDING)
End Function
' Spawn subprocess and wait for it to complete. ' I believe that the command in the command line must be an exe or a bat file. ' Maybe, however, it can reference any file the system knows how to "Open" ' ' commandLine is an executable. ' expectedDuration - is for poping up a dialog for whatever ' infoText - text for progressDialog dialog
Public Function ShellAndWait( commandLine As String, _
expectedDuration As Integer ) As Boolean Dim inst As Long Dim startTime As Long Dim expirationTime As Long Dim pid As Long Dim expiresSameDay As Boolean On Error GoTo HandleError
'Deal with timeout being reset at Midnight ($hitForBrains VB folks) startTime = CLng(Timer) expirationTime = startTime + expectedDuration expiresSameDay = expirationTime < 86400 If Not expiresSameDay Then expirationTime = expirationTime - 86400 End If
inst = Shell(commandLine, vbMinimizedNoFocus) If inst <> 0 Then pid = OpenProcess(PROCESS_QUERY_INFORMATION, False, inst)
Do While ProcessIsRunning( pid) DoEvents If Timer > expirationTime And (expiresSameDay Or Timer < startTime) Then Exit Do End If Loop ShellAndWait = True Else MsgBox ("Couldn't execute command: " & commandLine) ShellAndWait = False End If Exit Function
HandleError:
MsgBox ("Couldn't execute command: " & commandLine) ShellAndWait = False
End Function
Sub SpawnDir()
ShellAndWait("dir", 10)
End Sub
</VB>