如何在 Java 中检测类 Unix 操作系统?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3282498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:08:06  来源:igfitidea点击:

How can I detect a Unix-like OS in Java?

javaunix

提问by mluisbrown

Ok, I know that System.getProperty("os.name")will give me the name of the OS I'm running under, but that's not a lot of help. What I need to know is if the OS I'm running on is a 'Unix-like' OS, I don't care if it's HP-UX, AIX, Mac OS X or whatever.

好的,我知道这System.getProperty("os.name")会给我正在运行的操作系统的名称,但这并没有多大帮助。我需要知道的是,我运行的操作系统是否是“类 Unix”操作系统,我不在乎它是 HP-UX、AIX、Mac OS X 或其他什么。

From the list of possible os.name valuesit seems like a quick and dirty way of detecting a 'Unix-like' OS is checking if os.namedoes notcontain "Windows". The false positives that will give me are OSes my code is very unlikely to encounter! Still, I'd love to know a better way if there is one.

可能的os.name值列表看起来像检测“类Unix”操作系统,如果检查一个快速和肮脏的方式os.name没有包含的“Windows”。会给我带来的误报是我的代码不太可能遇到的操作系统!不过,如果有更好的方法,我很想知道。

采纳答案by David J. Liszewski

I've used your scheme in production code on Windows XP, Vista, Win7, Mac OS 10.3 - 10.6 and a variety of Linux distros without an issue:

我已经在 Windows XP、Vista、Win7、Mac OS 10.3 - 10.6 和各种 Linux 发行版上的生产代码中使用了你的方案,没有任何问题:

    if (System.getProperty("os.name").startsWith("Windows")) {
        // includes: Windows 2000,  Windows 95, Windows 98, Windows NT, Windows Vista, Windows XP
    } else {
        // everything else
    } 

Essentially, detect Unix-likeby notdetecting Windows.

本质上,通过检测 Windows 来检测类 Unix

回答by Pascal Thivent

Use the org.apache.commons.lang.SystemUtilsutility class from Commons Lang, it has a nice IS_OS_UNIXconstant. From the javadoc:

使用org.apache.commons.lang.SystemUtilsCommons Lang的实用程序类,它有一个很好的IS_OS_UNIX常量。从javadoc:

Is trueif this is a POSIX compilant system, as in any of AIX, HP-UX, Irix, Linux, MacOSX, Solaris or SUN OS.

The field will return false if OS_NAME is null.

true如果这是一个POSIX compilant系统,在任何AIX,HP-UX,IRIX的Linux,MacOSX的,Solaris或SUN OS的。

如果 OS_NAME 为空,该字段将返回 false。

And the test becomes:

测试变成:

if (SystemUtils.IS_OS_UNIX) {
    ...
}

Simple, effective, easy to read, no cryptic tricks.

简单,有效,易于阅读,没有神秘的技巧。

回答by MikeD

File.listRoots()will give you an array of the file system root directories.

File.listRoots()将为您提供文件系统根目录的数组。

If you are on a Unix-like system, then the array should contain a single entry "/"and on Windows systems you'll get something like ["C:", "D:", ...]

如果您在类 Unix 系统上,则该数组应包含一个条目,"/"而在 Windows 系统上,您将得到类似["C:", "D:", ...]

Edit:@chris_l: I totally forgot about mobile phones. Some digging turns up that Android returns a "/\0\0"- a slash followed by two null bytes (assumed to be a bug). Looks like we avoid false positives for the time being through luck and coincidence. Couldn't find good data on other phones, unfortunately.

编辑:@chris_l:我完全忘记了手机。一些挖掘结果表明,Android 返回了一个"/\0\0"- 一个斜杠,后跟两个空字节(假设是一个错误)。看起来我们通过运气和巧合暂时避免了误报。不幸的是,在其他手机上找不到好的数据。

It's probably not a good idea to run the same code on desktops and mobile phones regardless, but it is interesting to know. Looks like it comes down to needing to check for specific features instead of simply the system type.

无论如何,在台式机和移动电话上运行相同的代码可能不是一个好主意,但知道这一点很有趣。看起来归结为需要检查特定功能而不是简单的系统类型。

回答by stacker

Javadoc says: On UNIX systems the value of this * field is '/'; on Microsoft Windows systems it is '\'.

Javadoc 说:在 UNIX 系统上,这个 * 字段的值是'/'; 在 Microsoft Windows 系统上,它是'\'.

System.out.println( File.separatorChar == '/' ? "Unix" : "Windows" );

回答by stacker

System.getProperty("os.name");is about the best you are going to get.

System.getProperty("os.name");是关于你将得到的最好的。

回答by Brent Writes Code

I agree with @Fuzzy in that I think the only way that Java intended you to be able to get that information was through the os.nameproperty.

我同意@Fuzzy,因为我认为 Java 希望您能够获取该信息的唯一方式是通过该os.name属性。

The only other things I can think of are:

我唯一能想到的其他事情是:

  1. Have a shell script or batch file wrapper to launch your Java app that passes in OS information using the -Dargument to the JVM. Though given your description, this doesn't sound doable.

  2. You could try to check for the existence of an OS-specific directory. For instance, you could assume the directory "/"will always exist on a Unix-like system, but not on Windows and do something like this:

    if((new File("/")).exists()) { System.out.println("I'm on a Unix system!"); }

  3. Try to kick off a Unix-specific command line command like lsand check the return code. If it worked, you're on a Unix-like system, if not you're on Windows.

  1. 使用 shell 脚本或批处理文件包装器来启动您的 Java 应用程序,该应用程序使用-D参数将操作系统信息传递给 JVM。尽管根据您的描述,这听起来不可行。

  2. 您可以尝试检查是否存在特定于操作系统的目录。例如,您可以假设该目录"/"将始终存在于类 Unix 系统上,但不存在于 Windows 上,然后执行以下操作:

    if((new File("/")).exists()) { System.out.println("我在 Unix 系统上!"); }

  3. 尝试启动一个 Unix 特定的命令行命令ls并检查返回代码。如果它有效,那么您使用的是类 Unix 系统,否则您使用的是 Windows。

All of those solutions are really just hacks though and frankly I don't really feel all that great about any of them. You're unfortunately probably best off with your original thought. Fun, eh?

所有这些解决方案实际上都只是黑客,坦率地说,我对它们中的任何一个都没有那么好的感觉。不幸的是,您可能最适合您最初的想法。好玩吧?

回答by Greg Mallett

Use File.pathSeparator or File.separator. The first will return ";" in Windows and ":" in Unix. The second will return "\" in Windows and "/" in Unix.

使用 File.pathSeparator 或 File.separator。第一个将返回“;” 在 Windows 中,“:”在 Unix 中。第二个将在 Windows 中返回“\”,在 Unix 中返回“/”。

回答by neo7

Its a pretty old question to bump but still you can use this: System.getProperty("os.name").toLowerCase();

这是一个非常古老的问题,但您仍然可以使用它: System.getProperty("os.name").toLowerCase();

回答by Chris Lercher

You could try to execute the unamecommand - should be available on all unixoid systems.

您可以尝试执行该uname命令 - 应该在所有 unixoid 系统上都可用。

回答by Hiroki Horiuchi

package com.appspot.x19290;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class UnixCheck {
    public static void main(String[] args) {
        UnixCheck s = UnixCheck.S;
        String isUnix = s.unix ? "is Unix" : "not Unix";
        try {
            System.out.println(isUnix + ", devnull: " + s.devnull.getPath());
        } catch (NullPointerException e) {
            System.out.println(isUnix + ", devnull: unknown");
        }
    }

    public static final UnixCheck S = new UnixCheck();
    public static final UnixCheck TEST = new UnixCheck(true);

    public final boolean unix;
    public final File devnull;

    private UnixCheck() {
        this(false);
    }

    private UnixCheck(boolean testing) {
        String path;
        path = testing ? "/<dev>/<no><such><null><device>" : "/dev/null";
        File devnull = devnullOrNone(path);
        if (devnull == null) {
            this.unix = false;
            path = testing ? "<no><such><null><device>" : "nul";
            this.devnull = devnullOrNone(path);
        } else {
            this.unix = true;
            this.devnull = devnull;
        }
    }

    private static File devnullOrNone(String name) {
        File file = new File(name);
        if (file.isFile())
            return null;
        if (file.isDirectory())
            return null;
        try {
            FileInputStream i = new FileInputStream(file);
            try {
                i.read();
            } finally {
                i.close();
            }
        } catch (IOException e) {
            return null;
        }
        return file;
    }
}