java:runtime.exec获取linux发行版名称



我想检查发行版名称,但是我对bash contering命令有问题。为什么此代码可以正常运行并打印文件夹内容

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"};不?它根本没有打印任何东西,既不是错误也不打印。OFC。它在终端工作。这是怎么了?

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

我想一个选项是实际调用bash,让它为您处理:

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

,但我认为使用Java文件系统API搜索/etc以查找名称在-release中结束的文件并正常读取该文件的内容更有意义。(请参阅java.io.File的Javadoc和java.io.FileReader的Javadoc。)

尝试以下:

    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();
    }

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

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

最新更新