我正在尝试通过Java执行命令行参数。例如:
// Execute command
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);
// Get output stream to write from it
OutputStream out = child.getOutputStream();
out.write("cd C:/ /r/n".getBytes());
out.flush();
out.write("dir /r/n".getBytes());
out.close();
以上操作会打开命令行,但不会执行cd
或dir
。有任何想法吗?我正在运行Windows XP,JRE6。
(我已将我的问题修改为更具体。以下答案有帮助,但不回答我的问题。)
答案 0 :(得分:63)
我在forums.oracle.com
中找到了这个允许重用进程在Windows中执行多个命令:http://kr.forums.oracle.com/forums/thread.jspa?messageID=9250051
你需要像
这样的东西 String[] command =
{
"cmd",
};
Process p = Runtime.getRuntime().exec(command);
new Thread(new SyncPipe(p.getErrorStream(), System.err)).start();
new Thread(new SyncPipe(p.getInputStream(), System.out)).start();
PrintWriter stdin = new PrintWriter(p.getOutputStream());
stdin.println("dir c:\\ /A /Q");
// write any other commands you want here
stdin.close();
int returnCode = p.waitFor();
System.out.println("Return code = " + returnCode);
SyncPipe类:
class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
istrm_ = istrm;
ostrm_ = ostrm;
}
public void run() {
try
{
final byte[] buffer = new byte[1024];
for (int length = 0; (length = istrm_.read(buffer)) != -1; )
{
ostrm_.write(buffer, 0, length);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private final OutputStream ostrm_;
private final InputStream istrm_;
}
答案 1 :(得分:15)
如果要在cmd shell中运行多个命令,则可以构建一个如下命令:
rt.exec("cmd /c start cmd.exe /K \"cd c:/ && dir\"");
This page解释更多。
答案 2 :(得分:3)
exec
的每次执行都会产生一个拥有自己环境的新流程。所以你的第二次调用没有以任何方式连接到第一次。它只会改变自己的工作目录,然后退出(即它实际上是无操作)。
如果您想撰写请求,则需要在exec
的一次调用中执行此操作。如果Bash用分号分隔,Bash允许在一行上指定多个命令; Windows CMD可能允许相同,如果不存在,则始终存在批处理脚本。
As Piotr says,如果此示例实际您要实现的目标,则可以使用以下内容更有效,更有效,更安全地执行相同的操作:
String[] filenames = new java.io.File("C:/").list();
答案 3 :(得分:3)
您发布的代码会启动三个不同的进程,每个进程都有自己的命令。要打开命令提示符然后运行命令,请尝试以下操作(从未尝试过):
try {
// Execute command
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);
// Get output stream to write from it
OutputStream out = child.getOutputStream();
out.write("cd C:/ /r/n".getBytes());
out.flush();
out.write("dir /r/n".getBytes());
out.close();
} catch (IOException e) {
}
答案 4 :(得分:2)
答案 5 :(得分:1)
每个exec调用都会创建一个进程。第二次和第三次调用不在您在第一次调用中创建的同一shell进程中运行。尝试将所有命令放入bat脚本并在一次调用中运行它:
rt.exec("cmd myfile.bat");
或类似的
答案 6 :(得分:0)
这是因为每个runtime.exec(..)
返回一个Process
类,应该在执行后使用,而不是Runtime
类调用其他命令
如果查看Process doc,您会看到可以使用
getInputStream()
getOutputStream()
你应该通过发送连续命令和检索输出来工作..
答案 7 :(得分:0)
从流程写入流出的方向是错误的。在这种情况下,“出局”意味着从过程到你。尝试获取/写入进程的输入流并从输出流中读取以查看结果。
答案 8 :(得分:0)
由于我也面临同样的问题,并且因为这里的一些人评论说解决方案并不适合他们,所以这里是找到工作解决方案的帖子的链接。
https://stackoverflow.com/a/24406721/3751590
另见"更新"在使用Cygwin终端的最佳答案
答案 9 :(得分:0)
try {
String command = "Command here";
Runtime.getRuntime().exec("cmd /c start cmd.exe /K " + command);
} catch (IOException e) {
e.printStackTrace();
}
答案 10 :(得分:0)
这是一个不需要多个线程的简单示例:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class SimplePty
{
public SimplePty(Process process) throws IOException
{
while (process.isAlive())
{
sync(process.getErrorStream(), System.err);
sync(process.getInputStream(), System.out);
sync(System.in, process.getOutputStream());
}
}
private void sync(InputStream in, OutputStream out) throws IOException
{
while (in.available() > 0)
{
out.write(in.read());
out.flush();
}
}
public static void main( String[] args ) throws IOException
{
String os = System.getProperty("os.name").toLowerCase();
String shell = os.contains("win") ? "cmd" : "bash";
Process process = new ProcessBuilder(shell).start();
new SimplePty(process);
}
}