0

当我从 java 执行 linux 命令时,它不起作用任何人都可以帮助我解决这个问题。

process3 = Runtime.getRuntime().exec(new String[] {"ls",
                    "-1s", 
                     "--block-size=1",
                      TStamp+"/received/i*.*",
                      "$dir|",
                      "awk",
"'{print $2\"\\t\"$1}'",
                           ">>",
                  "./"+TStamp+"/qa/manifest_QAG.txt"});
InputStream in1 = process3.getInputStream();              
BufferedReader br1=new BufferedReader(new InputStreamReader(in1));
String line1 =null;
while((line1=br1.readLine())!=null)
{
System.out.println(line1);
} 

Edit1:我试图列出文件并在 manifest_QAG.txt 中生成清单

实际命令在 linux 中有效:

ls -1s --block-size=1 20130328094916142/received/is*.* $dir| awk '{print $2"\t"$1}'

Edit2:我没有得到任何异常,甚至没有创建文件 manifest_QAG.txt

编辑3:

4

3 回答 3

2

您没有收到异常,因为该ls命令不是 Java 并且不与异常通信,而是与错误消息STDERR和退出代码通信。

实际上,您必须了解当您输入命令时,shell 做了什么以及该命令做了什么。因此,像这样的 shell 命令行

ls -1s --block-size=1 20130328094916142/received/is*.* $dir| awk '{print $2"\t"$1}'

由外壳以这种方式处理:

  • shell:将其展开20130328094916142/received/is*.*为文件名列表
  • shell:将$dir部分扩展为文件名列表
  • shell:执行ls带有参数的命令
    • ls
    • -1s
    • --block-size=1
    • 每个扩展文件名作为单独的参数
  • shell:awk使用参数执行命令
    • {print ...}
  • shell:将输出连接ls到输入awk
  • ls:评估参数
  • awk:读取每一行,用给定的脚本处理它并输出结果。

您会看到:环境变量和通配符的扩展是由 shell 完成的,而不是由ls.

回到 Java: execute不像shell那样处理参数。那取决于你。因此,您的调用与 shell 等效,大致如下:

ls '-1s' '--block-size=1' '20130328094916142/received/is*.*' '$dir' '|' 'awk' '{print $2"\t"$1}'

一切都被引用了,甚至是管道,因此shell没有扩展任何内容。

问题到此为止。有哪些解决方案?

  • 您可以模拟 shell 并在 Java 中进行扩展。玩得开心。(即这不是一个真正的解决方案)。
  • 您可以从 Java 调用 shell 而不是ls.

后期是这样的:

shell 通常有一个-c选项,您可以给它一个命令字符串,然后以与实际键入的命令行相同的方式对其进行评估。

所以你像这样调用命令

String[] args = {
    "/bin/sh",
    "-c",
    "ls -1s --block-size=1 20130328094916142/received/is*.* $dir| awk '{print $2\"\t\"$1}'"
};
Process process3 = Runtime.getRuntime().exec(args);

尽管awk命令的正确引用可能需要更多的工作。

于 2013-03-28T15:24:30.523 回答
0

我认为这里有一些错字

/received/i*.* is different from one that is in linux command /received/is*.*

希望能帮助到你

于 2013-03-28T15:06:21.217 回答
0

管道 (|) 不是 ls 的参数,而是 shell 的一个功能。如果你想在 Runtime#exec 中使用这样的管道,你必须启动一个 shell,并将你希望 shell 解析和执行的命令字符串作为参数传递。

除非我遗漏了什么,否则列出目录并使用 Java 代码编写清单可能会更容易,而不是为琐碎的文件和字符串操作调用外部工具。

于 2013-03-28T15:21:04.360 回答