如何使用Java通过Windows/cygwin执行unix命令

Mar*_*osi 10 java unix shell cygwin windows-7

我想完成两件事:

  1. 我在Windows7上运行cygwin来执行我的unix shell命令,我需要通过编写Java应用程序来自动化该过程.我已经知道如何使用'Process class'和Java通过Java来使用windows shell Runtime.getRuntime().exec("cmd /c dir").我需要能够使用unix命令执行相同的操作:ie:ls -la等等.我该怎么看?

  2. 有没有办法记住shell的状态?解释:当我使用:时Runtime.getRuntime().exec("cmd /c dir"),我总是得到我的主目录列表.如果我这样做Runtime.getRuntime().exec("cmd /c cd <some-folder>")然后再做Runtime.getRuntime().exec("cmd /c dir"),我仍然会得到我的主文件夹的列表.有没有办法告诉进程记住它的状态,就像常规shell一样?


似乎bashPaŭlo提出的命令行不起作用:

C:\cygwin\bin>bash -c ls -la
-la: ls: command not found
Run Code Online (Sandbox Code Playgroud)

我无法搞清楚技术细节.

这是我的代码:

p = Runtime.getRuntime().exec("C:\\cygwin\\bin\\bash.exe -c ls -la");
reader2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
line = reader2.readLine();
Run Code Online (Sandbox Code Playgroud)

line 最终得到一个空值.


我把它添加到我的.bash_profile:

#BASH
export BASH_HOME=/cygdrive/c/cygwin
export PATH=$BASH_HOME/bin:$PATH
Run Code Online (Sandbox Code Playgroud)

我还添加了以下内容:

系统属性 - >高级 - >环境变量 - >用户variebales - >变量:BASH,值:c:\cygwin\bin

依然没有...

但是,如果我执行此操作,它会工作!

p = Runtime.getRuntime().exec("c:\\cygwin\\bin\\ls -la ~/\"Eclipse_Workspace/RenameScript/files copy\"");
Run Code Online (Sandbox Code Playgroud)

Paŭ*_*ann 11

1.调用unix命令:

你只需要调用你的unix shell(例如用cygwin提供的bash)而不是cmd.

bash -c "ls -la"
Run Code Online (Sandbox Code Playgroud)

应该做.当然,如果您的命令是外部程序,您可以直接调用它:

ls -la
Run Code Online (Sandbox Code Playgroud)

从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"});
Run Code Online (Sandbox Code Playgroud)

示例(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"});
Run Code Online (Sandbox Code Playgroud)

2.调用多个命令:

在一个shell中基本上有两种调用多个命令的方法:

  • 将它们全部传递给壳体; 要么
  • 以交互方式将它们传递给shell.

对于第一种方式,只需将多个命令作为-c选项的参数,用;或分隔\n(换行符),如下所示:

bash -c "cd /bin/ ; ls -la"
Run Code Online (Sandbox Code Playgroud)

或者来自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"});
Run Code Online (Sandbox Code Playgroud)

shell将命令行解析为,并将其作为脚本执行.如果它包含多个命令,如果shell由于某种原因(如exit命令)之前没有以某种方式退出,则它们都将被执行.(我不确定Windows cmd是否以类似的方式工作.请测试并报告.)

您可以通过Process'输入流传递它们,而不是传递bash(或cmd或您使用的任何shell)命令行上的命令.

  • 以"输入模式"启动的shell(例如,既没有-c选项也没有shell脚本文件参数的shell)将从流中读取输入,并将第一行解释为命令(或几个).
  • 然后它将执行此命令.如果需要,命令本身可能会从流中读取更多输入.
  • 然后shell将读取下一行,将其解释为命令,然后执行.
  • (在某些情况下,shell必须读取多行,例如对于长字符串或组合命令,如if或loops.)
  • 这将一直持续到流的末尾(例如你身边的stream.close())或执行显式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();
Run Code Online (Sandbox Code Playgroud)