Как я могу обнаружить Unix-подобную ОС на Java?
Хорошо, я знаю, что System.getProperty("os.name")
даст мне имя операционной системы, в которой я запущен, но это не очень помогает. То, что мне нужно знать, это то, что ОС, на которой я работаю, является "Unix-подобной" ОС, мне все равно, есть ли она HP-UX, AIX, Mac OS X или что-то еще.
Из списка возможных значений os.name кажется, что быстрый и грязный способ обнаружения "Unix-подобной" ОС проверяет если os.name
содержит не, содержащее "Windows". Фальшивые срабатывания, которые дадут мне, - это операционные системы, с которыми мой код вряд ли встретится! Тем не менее, я хотел бы узнать лучший способ, если он есть.
Ответы
Ответ 1
Я использовал вашу схему в производственном коде в 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
}
По существу, обнаруживайте Unix-подобные, используя не, обнаруживая Windows.
Ответ 2
Используйте утилитный класс org.apache.commons.lang.SystemUtils
из Commons Lang, он имеет хороший IS_OS_UNIX
константа. Из javadoc:
Является true
, если это компилятор POSIX система, как в любом из AIX, HP-UX, Irix, Linux, MacOSX, Solaris или SUN OS.
Поле вернет false, если OS_NAME имеет значение null.
И тест будет следующим:
if (SystemUtils.IS_OS_UNIX) {
...
}
Простой, эффективный, легко читаемый, без загадочных трюков.
Ответ 3
File.listRoots()
предоставит вам массив корневых каталогов файловой системы.
Если вы используете Unix-подобную систему, тогда массив должен содержать одну запись "/"
, а в системах Windows вы получите что-то вроде ["C:", "D:", ...]
Изменить: @chris_l: Я полностью забыл о мобильных телефонах. Некоторый рывок показывает, что Android возвращает "/\0\0"
- слэш, за которым следуют два нулевых байта (предполагается, что это ошибка). Похоже, что мы избегаем ложных срабатываний на время удачи и совпадения. Не удалось найти хорошие данные на других телефонах, к сожалению.
Вероятно, неплохо запускать один и тот же код на настольных компьютерах и мобильных телефонах, но это интересно. Похоже, дело сводится к необходимости проверки определенных функций вместо простого типа системы.
Ответ 4
Javadoc говорит: В системах UNIX значение этого * поле '/'
; в системах Microsoft Windows это '\'
.
System.out.println( File.separatorChar == '/' ? "Unix" : "Windows" );
Ответ 5
System.getProperty("os.name");
- это лучшее, что вы собираетесь получить.
Ответ 6
Я согласен с @Fuzzy в том, что, я думаю, единственный способ, которым Java намеревался получить эту информацию, - это свойство os.name
.
Единственное, что я могу придумать, это:
-
У вас есть оболочка script или пакетный файл для запуска вашего приложения Java, которое передает информацию о ОС, используя аргумент -D
для JVM. Несмотря на ваше описание, это не кажется выполнимым.
-
Вы можете попробовать проверить наличие каталога, специфичного для ОС. Например, вы можете предположить, что каталог "/"
всегда будет существовать в Unix-подобной системе, но не в Windows и делать что-то вроде этого:
if ((новый файл ( "/" )). exists())
{ System.out.println( "Я нахожусь в системе Unix!" );
}
-
Попробуйте запустить команду командной строки, специфичную для Unix, например ls
и проверьте код возврата. Если это сработало, вы используете Unix-подобную систему, если не находитесь в Windows.
Все эти решения - действительно просто хаки, хотя, честно говоря, я действительно не чувствую в этом ничего хорошего. Вы, к сожалению, вероятно, лучше всего со своей оригинальной мыслью. Удовольствие, а??
Ответ 7
Используйте File.pathSeparator или File.separator. Первый вернет ";" в Windows и ":" в Unix. Второй вернет "\" в Windows и "/" в Unix.
Ответ 8
Его довольно старый вопрос, но все же вы можете использовать его: System.getProperty("os.name").toLowerCase();
Ответ 9
Вы можете попробовать выполнить команду uname
- должны быть доступны во всех системах unixoid.
Ответ 10
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;
}
}