【问题标题】:Execute shell script in Java and read Output在 Java 中执行 shell 脚本并读取输出
【发布时间】:2015-03-08 05:55:10
【问题描述】:

我在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=$1
value=`$2` 
echo $value

当我直接使用 key 和 value 执行 jj.sh 时,它给了我正确的值,即文件名。 但是对于 java,它给我的结果是 ls -1 结果(意味着 java 忽略了 '|' 之后的命令)。当我传递用波浪号 ` 分隔的键值时,它只会显示完整的键值,即 ls -1|tail -1

如何使用java执行完整的命令

【问题讨论】:

  • 直接做jj.sh怎么跑?
  • 您可能必须使用您希望此脚本在其中运行的 shell 的完整路径作为第一个参数; hash-bang 对 Java 生成的 exec shell 可能没有意义。此外,您将不得不密切注意某些字符是如何转义的,因为这些内容被解析了不止一次。
  • 问题Running shell script from java code and pass arguments可能对你有帮助。特别是从runtime.exec() 切换到process.start()。同样,外壳也不是。您应该 invoke the shell 并将脚本作为参数传递给它。
  • 首先,您的 Java 代码实际上并没有编译。您没有关闭 if 块。我允许的变量都是字符串。但是,你写了ls-1|tail-1 没有空格,这永远不会飞。但是,您的 shell 脚本实际上并不能与管道一起使用。您可能以jj.sh key ls -1| tail -1 运行它,它实际上运行jj.sh key ls -1,然后将输出传递给tail -1
  • @Jagdeep 当我使用您的脚本运行该命令时,我得到“ls: invalid option -- '|'尝试使用 `ls --help' 获取更多信息。”。当你复制粘贴你的命令时你会得到什么?确保将命令实际复制粘贴到终端中,并且不要运行您认为等效的东西。

标签: java linux bash shell


【解决方案1】:

这不起作用的主要原因是`$2``ls -1 | tail -1` 不同,即使$2 设置为该字符串也是如此。

如果您的脚本接受带有要执行的命令的文字字符串,您可以使用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="$1"                                   
value=$(eval "$2")                             
echo "The command  $2  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 

【讨论】:

    【解决方案2】:

    正如其他张贴者已经指出的那样,子进程不是在 shell 中启动的,所以 she-bang 没有被解释。

    我通过在 jj.sh 的 shell 中显式启动第二个参数的评估来让你的示例工作:

    value=`sh -c "$2"` 
    

    不好,但可以。

    其他选项可能是在 shell 中显式启动脚本,模拟 sh-bang:

    String[] cmd = { "/bin/sh", "jj.sh" , key,value};
    

    【讨论】:

    • 它确实运行了she-bang。尝试编写一个只有 she-bang 和 ps $$ 的 shell 脚本,并通过上述程序的(更正形式)运行它。
    猜你喜欢
    • 2015-04-17
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多