我正试图完成两件事情:
我在Windows7上运行cygwin来执行我的UNIX命令,我需要通过编写一个Java应用程序来自动执行这个过程。 我已经知道如何通过Java使用'Process class'和Runtime.getRuntime().exec("cmd /c dir")
来使用windows shell。 我需要能够用unix命令做同样的事情,例如: ls -la
等等。 我应该看什么?
有没有办法记住一个shell的状态? 解释:当我使用: Runtime.getRuntime().exec("cmd /c dir")
,我总是得到我的主目录的列表。 如果我做了Runtime.getRuntime().exec("cmd /c cd <some-folder>")
,然后再执行Runtime.getRuntime().exec("cmd /c dir")
,我仍然会得到我的家庭文件夹。 有没有办法让程序记住它的状态,就像普通的shell一样?
看来Paŭlo提出的bash
命令行不起作用:
C:\cygwin\bin>bash -c ls -la -la: ls: command not found
我很难搞清楚技术问题。
这是我的代码:
p = Runtime.getRuntime().exec("C:\\cygwin\\bin\\bash.exe -c ls -la"); reader2 = new BufferedReader(new InputStreamReader(p.getInputStream())); line = reader2.readLine();
line
结束了一个空值。
我将这添加到我的.bash_profile:
#BASH export BASH_HOME=/cygdrive/c/cygwin export PATH=$BASH_HOME/bin:$PATH
我还添加了以下内容:
系统属性 – >高级 – >环境variables – >用户variebales – >variables:
BASH
,值:c:\cygwin\bin
依然没有…
但是,如果我执行此代替,它的工作原理!
p = Runtime.getRuntime().exec("c:\\cygwin\\bin\\ls -la ~/\"Eclipse_Workspace/RenameScript/files copy\"");
1.调用unix命令:
你只需要调用你的unix shell(比如用cygwin交付的bash)而不是cmd
。
bash -c "ls -la"
应该做。 当然,如果你的命令是一个外部程序,你可以直接调用它:
ls -la
当从Java开始时,最好使用带有字符串数组的变体,因为您没有让Java分析它来查看参数开始和结束的位置:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe", "-c", "ls -la"}, new String[]{"PATH=/cygdrive/c/cygwin/bin"});
你的例子中的错误信息( ls: command not found
)似乎表明你的bash找不到ls
命令。 也许你需要把它放到PATH变量中(参见上面的Java方法)。
也许不是/cygdrive/c/cygwin/bin
,正确的目录名称是/usr/bin
。
(因为必须在Unix和Windows协议之间进行桥接,所以一切都变得复杂了。)
简单的ls
命令可以这样调用:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\ls.exe", "-la"});
2.调用多个命令:
基本上有两种在一个shell中调用多个命令的方法:
对于第一种方法,只需将多个命令作为参数传递给-c
选项, 或\n
(换行符),如下所示:
bash -c "cd /bin/ ; ls -la"
或从Java(适应上面的例子):
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe", "-c", "cd /bin/; ls -la"}, new String[]{"PATH=/cygdrive/c/cygwin/bin"});
在这里,shell将解析命令行,并将其作为脚本执行。 如果它包含多个命令,它们将被全部执行,如果shell由于某种原因(如exit
命令)之前不以某种方式退出。 (我不确定Windows cmd
是否能以类似的方式工作,请测试并报告。)
命令行上的命令不是通过bash(或cmd或任何你正在使用的shell),而是通过Process的输入流传递它们。
-c
选项也没有shell脚本文件参数的shell)将从流中读取输入,并将第一行解释为命令(或多个命令)。 exit
命令(或其他一些exit
命令)。 这将是一个例子:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe", "-s"}); InputStream outStream = p.getInputStream(); // normal output of the shell InputStream errStream = p.getInputStream(); // error output of the shell // TODO: start separate threads to read these streams PrintStream ps = new PrintStream(p.getOutputStream()); ps.println("cd /bin/"); ps.println("ls -la"); ps.println("exit"); ps.close();
这里你不需要cygwin。 有几个纯Java库实现SSH协议。 使用它们。 顺便他们会解决你的第二个问题。 您将打开会话并执行相同会话的命令,因此shell状态将自动保留。
JSch就是一个例子。