Runtime.getRuntime(). exec( )

该博客主要围绕Java术语exec展开,介绍了其相关定义,页面显示最后更新时间为2005年1月11日,版权归Canadian Mind Products所有,还给出了Java定义的索引导航。

Java Glossary : exec

CMP home Java glossary home Menu no menu Last updated 2005-01-11 by Roedy Green ©1996-2005 Canadian Mind Products

Java definitions: 0-9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

You are here : home : Java Glossary : E words : exec.

exec
Runtime.getRuntime(). exec( "myprog.exe" ) will spawn an external process that runs in parallel with the Java execution. In Windows 95/98/ME/NT/W2K/XP/W2K3, you must use an explicit *.exe or *.com extension on the parameter. It is also best to fully qualify those names so that the system executable search path is irrelevant, and so you don't pick up some stray program off the path with the same name.

There are also overloaded forms of exec(),

Runtime.getRuntime().exec ( "command.com /E:1900 /C MyBat.bat", null );
Runtime.getRuntime().exec ( "command.com /E:1900 /C MyBat.bat", null, "C://SomeDirectory" );

The second argument can be a String [], and can be used to set environment variables. In the second case, "C://SomeDirectory" specifies a directory for the process to start in. If, for instance, your process saves files to disk, then this form allows you to specify which directory they will be saved in.

Command Interpter

To run a *.BAT, *.CMD, *.html *.BTM or URL you must invoke the command processor with these as a parameter. These extensions are not first class executables in Windows. They are input data for the command processor. You must also invoke the command processor when you want to use the < > | piping options, Here's how, presuming you are not interested in looking at the output:

// Windows 98 command.com
Runtime.getRuntime().exec ("command.com /E:1900 /C MyBat.bat" );

// Windows NT/W2K/XP cmd.exe
Runtime.getRuntime().exec ("cmd.exe /E:1900 /C MyCmd.cmd" );

// Windows 98 with 4DOS
Runtime.getRuntime().exec ("C://4DOS601//4DOS.COM /E:1900 /C MyBtm.btm" );

// Windows NT/W2K/XP with 4NT
Runtime.getRuntime().exec ("C://4NT401//4NT.EXE /E:1900 /C MyBtm.btm" );

// Linux Bash
String[] cmd = {"/bin/bash", "-c", "rm /dirA/*"};
Runtime.getRuntime().exec ( cmd );

exec only understands xxx.exe and parameters. It knows nothing about program names without the *.exe explicitly mentioned, | pipes, < redirection >, % environment parameter subsitution, or *.bat, *.cmd or *.html files. For all those things you must spawn a command interpreter/shell script with an explcit .exe extension and pass it the name of your executable as a parameter.

Windows and NT will let you feed a URL string to the command processor and it will find a browser, launch the browser, and render the page, e.g.

Runtime.getRuntime().exec ("command.com http://mindprod.com/ects.html" );

Another lower level approach that does not require extension associations to be quite as well set up is:

Runtime.getRuntime().exec ("rundll32 url.dll,FileProtocolHandler http://mindprod.com/ects.html" );

Note that a URL is not the same thing as a file name. You can point your browser at a local file with something like this: file://localhost/E:/mindprod/jgloss.html or file:///E|/mindprod/jgloss.html.

Composing just the right platform-specific command to launch browser and feed it a URL to display can be frustrating. You can use the BrowserLauncher package to do that for you.

Note that

rundll32.exe url.dll,FileProtocolHandler file:///E|/mindprod/jgloss.html

won't work on the command line because | is reserved as the piping operator, though it will work as an exec parameter passed directly to the rundll32.exe executable.

With explicit extensions and appropriately set up associations in Windows 95/98/ME/NT/W2K/XP/W2K3 you can often bypass the command processor and invoke the file directly, even *.bat.

Similarly, for Unix/Linux you must spawn the program that can process the script, e.g. bash. However, you can run scripts directly with exec if you do two things:

  1. Start the script with #!bash or whatever the interpreter's name is.
  2. Mark the script file itself with the executable attribute.
Alternatively start the script interpreter, e.g.

Runtime.getRuntime().exec (new String[]{"/bin/sh", "-c", "echo $SHELL"}

Communicating With The Spawned Process

exec returns a Process object that you can use to control, monitor or wait for the background process like this:


view

Process.getOutputStream lets you write out data that will be used as input to the process. Don't forget to include any "/n" and "/r" characters the process is expecting. Process.getInputStream lets you read in the data that your process squirted out to stdout. In a complex case you could have four threads:

  1. The original
  2. One to wait for child termination
  3. One to provide the data for the child.
  4. One to read the responses from the child.

The other cruder way to get the output from the execed program is to spawn a command processor and use the > or 2> redirection operator to direct stdout or stderr to a file. When the spawned program completes, read the file.

If you wait for the Process, you might want to do it on some thread other than the main AWT event processing one, i.e. create a new Thread, otherwise your app will not be able to process AWT events while you wait.

In general you need to write to STDOUT and read from STDIN with separate threads to avoid deadlocks. The deadlock occurs if you try to read and/or write more than a certain amount (empirically it is around 4k).

You can't use exec from an Applet otherwise you would be able to wreck havoc on the client machine by spawning FORMAT C:. If you need to do that, you will need to have a signed Applet with high privilege.

Applets

If you are in an Applet and all you are trying to is get a browser to render a page, you don't need exec. Simply use getAppletContext().showDocument( new URL("http://domain/file.html"));

Simplifications

There is also Marty Hall's Exec class, which simplifies the process of using exec and tends to make the command more stable. Currently, only the exec(String cmd) is supported, with a workaround for exec(String cmd, null, String dir)

Gotchas

If you are used to C exec, watch out. Java does not use the dummy parameter 0 which duplicates the name of the program. In a similar way, Java main methods don't see that dummy parameter either. You will need a tee utility to see the output both on screen and captured to a file.


CMP logo
CMP_home
home
Canadian Mind ProductsCSS
HTML Checked!
ICRA ratings logo
mindprod.com IP:[24.87.56.253]
Your IP:[219.238.233.20]
You are visitor number 24513.
Please send errors, omissions and suggestions
to improve this page to Roedy Green.
You can get a fresh copy of this page from:or possibly from your local J: drive mirror:
http://mindprod.com/jgloss/exec.htmlJ:/mindprod/jgloss/exec.html
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值