【问题标题】:shell Command execution Failing when executed from Java从Java执行shell命令执行失败
【发布时间】:2013-08-06 13:06:44
【问题描述】:

当我在命令行上执行以下命令时,它会显示 sybase DB 中的所有存储过程和表。

printf 'sp_help\ngo\n' | isql -Uxx -Pxxxx -Dxxxxx

但是当我在 java 中做同样的事情时。这不会返回任何结果。 谁能告诉我下面的代码有什么问题:

public class test
{
  public static void main(String[] args)
  {
   String cmd = "printf "+"\'sp_help\ngo\n\'"+"| isql -Uxx -Pxxxx -Dxxxxx" ;
   try{ 
          Process p;
          p = Runtime.getRuntime().exec(cmd);
          p.waitFor();
          String line; 
          BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

           while ((line = reader.readLine())!=null){
           System.out.println("Row is :" + line);
   } catch(Exception e)
       {
           System.out.println("Exception Caught : " + e);
       }

  }

}

编辑 我按照 Darkdust 的建议执行了它,但它仍然不起作用。

try{
          Process p;
          p = Runtime.getRuntime().exec("sh -c \'printf \"sp_help\ngo\n\" | isql -Uxx -Pxxxxx -Dxxxxxx\'");
          p.waitFor();
          String line;
          BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

           while ((line = reader.readLine())!=null){
           System.out.println("Row is :" + line);
  }
 }
       catch(Exception e)
       {
           System.out.println("Exception Caught : " + e);
       }

但是命令:

sh -c 'printf "sp_help\ngo\n" | isql -Usa -Psybase11 -Dcnadb'

在命令行上工作。

我也试过了:

p = Runtime.getRuntime().exec(new String[]{"sh","-c","\'printf \"sp_help\ngo\n\"","|isql -Uxx -Pxxxxx -Dxxxxx\'"});

但没有成功。

【问题讨论】:

    标签: java command-line sybase


    【解决方案1】:

    我想到了几件事:

    • 不完整的 PATH 环境变量(因此无法找到 isql)。
    • 如果它是您提供的命令,而不是弄乱 PATH,您可能希望确保您在正确的工作目录中,并改为调用 ./isql
    • 由于您使用的是管道,因此您应该像sh -c "foo | bar" 一样让shell 执行此操作。否则,| isql ... 部分也会作为参数传递给 printf

    【讨论】:

    • isql 路径可用。正如我所说,该命令从命令行按预期运行。为什么在java中没有按预期运行?我认为整个cmd 将在命令行上执行,输出将被检索到java
    • 见我的最后一点。 Java 可能会运行“printf”并将 everything 作为参数传递给“printf”,甚至是管道符号和之后的所有内容。您需要运行一个 shell 并让它运行您的命令,如sh -c "printf 'sp_help\ngo\n' | isql -Uxx -Pxxxx -Dxxxxx"。您可能想使用带有String[] 参数的exec 变体:IIRC,它应该是Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd});(我的Java 生锈了)。
    • 好的..我明白你的意思了。但是我现在面临的问题是sh -c "printf "sp_help\ngo\n" | isql -Uxx -Pxxx -Dxxxxx" 不能在命令行本身上工作,如果我将sh -c 添加为命令的前缀。它给了我一个错误用法:printf 格式 [参数...]
    • 不,我不是要写一个 bash 脚本。在 shell 上,您需要输入 sh -c 'printf "sp_help\ngo\n" | isql -Uxx -Pxxx -Dxxxxx'(或使用 " 并使用 \" 将它们转义)。很可能您需要做的就是用p = Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd}); 替换您的p = ... 行(在这种情况下,不需要额外的" 转义)。你试过吗?
    • 你解决了这个问题吗?