我试图在我的Java程序中运行以下命令
Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log | awk '{print $9}'");
or
Runtime.getRuntime().exec("ls -lrt service/logs/post/level2* | awk '{print $9}'");
Run Code Online (Sandbox Code Playgroud)
它给了我以下错误
ls: 0653-341 The file | does not exist.
ls: 0653-341 The file awk does not exist.
ls: 0653-341 The file '{print does not exist.
ls: 0653-341 The file $9}' does not exist.
请帮助我
管道是基于shell的构造,而不是实际的可运行命令.我看到它有两种选择:
ls命令,获取它的句柄OutputStream,然后调用awk将第一个Process输出连接到第二个Process'输入流.-c参数.这样,所有管道都在单个过程中完成.对于基于令牌的错误,您应该使用字符串数组调用这些命令; 每个元素代表命令行的标记.所以试试,例如:
Runtime.getRuntime().exec(new String[] { "ls", "-lrt", "service/logs/post/level2.log" });
Run Code Online (Sandbox Code Playgroud)
为了调用ls命令.在这种情况下,我不认为这是绝对必要的,但它将用于awk命令,因为Java对shell特定的引用规则一无所知,因此默认情况下标记空格字符上的单字符串输入.这就是你的awk脚本分成两部分的原因.
编辑(回应评论):在第一个选项中,我只是说你能够用Java自己在两个进程之间管道输出.
想象一下,如果你已经创建了一个过程:
Process ls = Runtime.getRuntime().exec("ls -lrt service/logs/post/level2.log");
Run Code Online (Sandbox Code Playgroud)
现在,这个过程将运行并生成一些输出(我们知道这将是描述该文件的一行).我们可以像这样得到这个输出的流:
InputStream lsOut = ls.getInputStream();
Run Code Online (Sandbox Code Playgroud)
现在,我们想运行awk进程:
Process awk = Runtime.getRuntime().exec(new String[] { "awk", "{print $9}"});
Run Code Online (Sandbox Code Playgroud)
awk过程当然会坐在等待输入的那一刻,因为它知道它将从stdin读取.所以,我们抓住它将要使用的输入流:
OutputStream awkIn = awk.getOutputStream();
Run Code Online (Sandbox Code Playgroud)
现在,管道位 - 我们读取ls命令的输出并将其传递给awk的输入:
// TODO add buffering, error handling, probably run this in a separate thread
int datum = lsOut.read();
while (datum != -1)
{
awkIn.write(datum);
datum = lsOut.read();
}
Run Code Online (Sandbox Code Playgroud)
这读取输出ls(为了简单,逐字节,使用字节数组缓冲区会快得多,但我试图简单地说明这个概念)并将其写入输入awk.
然后,只需要从awk过程中读取输出并按照您认为合适的方式处理它.
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |