2

我想检查发行版名称,但 bash 执行命令时遇到问题。为什么此代码可以正常工作并打印文件夹内容

String cmd[] = {"ls","-a"};
Runtime run = Runtime.getRuntime(); 
try {
    Process proc = run.exec(cmd);
    BufferedReader read=new BufferedReader(new InputStreamReader(proc.getInputStream()));
    while(read.ready()) {
        System.out.println(read.readLine());
    }
} catch (IOException e) {
    e.printStackTrace();
}   

cmd[] = {"cat","/etc/*-release"};不是吗?它根本不打印任何东西,既不是错误也不是发行版。办公室。它在终端中工作。那有什么问题?

4

3 回答 3

4

它在 Bash 中工作的原因是 Bash 将其识别/etc/*-release为 glob 并执行必要的文件名扩展。Process不这样做;它只是cat使用您指定的确切参数调用。(换句话说,您正在运行相当于 Bash 命令cat '/etc/*-release'。)

我想,一种选择是实际调用 Bash 并让它为您处理:

String cmd[] = { "bash", "-c", "cat /etc/*-release" };

但我认为使用 Java 文件系统 API 搜索/etc名称以 结尾的文件-release并正常读取该文件的内容更有意义。(请参阅Javadoc forjava.io.FileJavadoc forjava.io.FileReader。)

于 2012-10-26T19:16:53.470 回答
0

试试这个:

    String[] cmd = {
    "/bin/sh", "-c", "cat /etc/*-release" };

    try {
        Process p = Runtime.getRuntime().exec(cmd);
        BufferedReader bri = new BufferedReader(new InputStreamReader(
                p.getInputStream()));

        String line = "";
        while ((line = bri.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {

        e.printStackTrace();
    }
于 2012-10-26T19:22:32.953 回答
0

Runtime.exec不调用 shell(例如 bash),而是直接启动进程。当您输入ls /etc/*-releasebash 时,bash 本身负责将 * 扩展为与该模式匹配的所有文件名。因此,当 bash 调用 ls 命令时, ls 将实际文件名视为参数。另一方面,当您的 java 代码调用 ls 命令时,ls 会看到实际的字符串“/etc/*-release”,这是一个不存在的文件。

最简单的解决方法是通过 /etc/lsb-release。更好的解决方案是调用lsb_release -c.

于 2012-10-26T19:26:19.477 回答