我正在努力完成两件事:
我在Windows7上运行cygwin来执行我的unix shell命令,我需要通过编写Java应用程序来自动化该过程。我已经知道如何使用'Process class'和Runtime.getRuntime().exec("cmd /c dir")
通过Java使用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
我还添加了以下内容:
系统属性 - &gt;高级 - &gt;环境变量 - &gt;用户variebales - &gt;变量:
BASH
,值:c:\cygwin\bin
仍然没有...
但是,如果我执行此操作,它会起作用!
p = Runtime.getRuntime().exec("c:\\cygwin\\bin\\ls -la ~/\"Eclipse_Workspace/RenameScript/files copy\"");
答案 0 :(得分:10)
<强> 1。调用unix命令:
你只需要调用你的unix shell(例如用cygwin提供的bash)而不是cmd
。
bash -c "ls -la"
应该这样做。当然,如果你的命令是外部程序,你可以直接调用它:
ls -la
从Java开始时,最好使用带有字符串数组的variant,然后使用 你没有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
命令(或退出的其他一些原因)。这是一个例子:
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();
答案 1 :(得分:1)
你这里不需要cygwin。有几个实现SSH协议的纯Java库。使用它们。 BTW他们将解决你的第二个问题。您将使用相同的会话打开会话和执行命令,因此将自动保留shell状态。
一个例子是JSch。