在 Java 中执行 shell 脚本并读取输出
Execute shell script in Java and read Output
我正在 java
中使用以下方法执行 shell 脚本
public static void main(String ar[])
{
//key value are being read from properties file, here I am assigning the sample values directly
key=mine
value="ls-1|tail-1"
String[] cmd = { "jj.sh" , key,value};
Process script_exec = Runtime.getRuntime().exec(cmd);
script_exec.waitFor();
if(script_exec.exitValue() != 0){
System.out.println("Error while executing script");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(script_exec.getInputStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
}
jj.sh 文件包含以下值
#!/bin/sh
key=
value=``
echo $value
当我直接使用键和值执行jj.sh时,它给了我正确的值,即文件名。
然而,使用 java 它给我的结果是 ls -1 结果(意味着 java 忽略了'|'之后的命令)。当我传递用波浪号分隔的键值时,它只显示完整的键值,即 ls -1|tail -1
如何使用 java
执行完整命令
正如其他发帖者已经指出的那样,子进程没有在 shell 中启动,所以 she-bang 没有被解释。
我通过在 jj.sh 中的 shell 中显式开始计算第二个参数来让你的示例工作:
value=`sh -c ""`
不太好,但有效。
其他选项可能是在 shell 中显式启动脚本,模拟 sh-bang:
String[] cmd = { "/bin/sh", "jj.sh" , key,value};
这不起作用的主要原因是 ``
与 `ls -1 | tail -1`
不同,即使 </code> 设置为该字符串也是如此。 </p>
<p>如果您的脚本接受带有要执行的命令的文字字符串,您可以使用 <code>eval
来执行此操作。
我创建了一个完整的例子。在尝试将其中任何一个应用到您自己的代码之前,请复制粘贴它并验证它是否有效。这是 Test.java
:
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
String[] command = { "./myscript", "key", "ls -t | tail -n 1" };
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String s;
while ((s = reader.readLine()) != null) {
System.out.println("Script output: " + s);
}
}
}
和myscript
:
#!/bin/bash
key=""
value=$(eval "")
echo "The command evaluated to: $value"
以下是我们如何 运行 myscript
分开:
$ ls -t | tail -n 1
Templates
$ ./myscript foo 'ls -t | tail -n 1'
The command ls -t | tail -n 1 evaluated to: Templates
这是 运行 宁 Java 代码的结果:
$ javac Test.java && java Test
Script output: The command ls -t | tail -n 1 evaluated to: Templates
我正在 java
中使用以下方法执行 shell 脚本public static void main(String ar[])
{
//key value are being read from properties file, here I am assigning the sample values directly
key=mine
value="ls-1|tail-1"
String[] cmd = { "jj.sh" , key,value};
Process script_exec = Runtime.getRuntime().exec(cmd);
script_exec.waitFor();
if(script_exec.exitValue() != 0){
System.out.println("Error while executing script");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(script_exec.getInputStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
}
jj.sh 文件包含以下值
#!/bin/sh
key=
value=``
echo $value
当我直接使用键和值执行jj.sh时,它给了我正确的值,即文件名。
然而,使用 java 它给我的结果是 ls -1 结果(意味着 java 忽略了'|'之后的命令)。当我传递用波浪号分隔的键值时,它只显示完整的键值,即 ls -1|tail -1
如何使用 java
执行完整命令正如其他发帖者已经指出的那样,子进程没有在 shell 中启动,所以 she-bang 没有被解释。
我通过在 jj.sh 中的 shell 中显式开始计算第二个参数来让你的示例工作:
value=`sh -c ""`
不太好,但有效。
其他选项可能是在 shell 中显式启动脚本,模拟 sh-bang:
String[] cmd = { "/bin/sh", "jj.sh" , key,value};
这不起作用的主要原因是 ``
与 `ls -1 | tail -1`
不同,即使 </code> 设置为该字符串也是如此。 </p>
<p>如果您的脚本接受带有要执行的命令的文字字符串,您可以使用 <code>eval
来执行此操作。
我创建了一个完整的例子。在尝试将其中任何一个应用到您自己的代码之前,请复制粘贴它并验证它是否有效。这是 Test.java
:
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
String[] command = { "./myscript", "key", "ls -t | tail -n 1" };
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String s;
while ((s = reader.readLine()) != null) {
System.out.println("Script output: " + s);
}
}
}
和myscript
:
#!/bin/bash
key=""
value=$(eval "")
echo "The command evaluated to: $value"
以下是我们如何 运行 myscript
分开:
$ ls -t | tail -n 1
Templates
$ ./myscript foo 'ls -t | tail -n 1'
The command ls -t | tail -n 1 evaluated to: Templates
这是 运行 宁 Java 代码的结果:
$ javac Test.java && java Test
Script output: The command ls -t | tail -n 1 evaluated to: Templates