Как проверить, работает ли Cygwin, Mac или Linux?

У меня есть сценарий оболочки, который используется как в Windows/Cygwin, так и в Mac и Linux. Для каждой версии требуются несколько разные переменные.

как скрипт оболочки/bash может определить, работает ли он в Cygwin, на Mac или в Linux?

10 ответов


как правило, uname С его различными вариантами расскажет вам, в какой среде вы работаете:

pax> uname -a
CYGWIN_NT-5.1 IBM-L3F3936 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin

pax> uname -s
CYGWIN_NT-5.1

и, согласно очень полезным schot (в комментариях), uname -s дает Darwin для OSX и Linux для Linux, в то время как мой Cygwin дает CYGWIN_NT-5.1. Но вам, возможно, придется экспериментировать со всеми видами различных версий.

так bash код для такой проверки будет примерно таким:

unameOut="$(uname -s)"
case "${unameOut}" in
    Linux*)     machine=Linux;;
    Darwin*)    machine=Mac;;
    CYGWIN*)    machine=Cygwin;;
    MINGW*)     machine=MinGw;;
    *)          machine="UNKNOWN:${unameOut}"
esac
echo ${machine}

обратите внимание, что я предполагаю, что вы на самом деле работает внутри CygWin (the bash shell of it), поэтому пути уже должны быть правильно настроены. Как отмечает один комментатор, вы можете запустить bash программа, передающая скрипт, от cmd и это может привести к тому, что пути не будут настроены по мере необходимости.

если вы are делая это, вы несете ответственность за то, чтобы правильные исполняемые файлы (т. е. CygWin) вызывались, возможно, путем изменения путь заранее или полностью указав исполняемые местоположения (например,/c/cygwin/bin/uname).


вот сценарий bash, который я использовал для обнаружения трех разных типов ОС (GNU/Linux, Mac OS X, Windows NT)

обратите внимание

  • в вашем сценарии bash используйте #!/usr/bin/env bash вместо #!/bin/sh для предотвращения проблемы, вызванной /bin/sh связанный с другой оболочкой по умолчанию на разных платформах, или будет ошибка, как неожиданный оператор, это то, что произошло на моем компьютере (Ubuntu 64 бит 12.04).
  • Mac OS X 10.6.8 (снег Leopard) не имеют expr программа, если вы не установите ее, поэтому я просто использую uname.

конструкция

  1. использовать uname для получения системной информации (

использовать uname -s (--kernel-name), поскольку uname -o (--operating-system) не поддерживается в некоторых операционных системах как Mac OS, Солярис. Вы также можете использовать просто uname без аргументов в качестве аргумента по умолчанию:-s (--kernel-name).

приведенный ниже фрагмент не требует Баш (т. е. не требует #!/bin/bash)

#!/bin/sh

case "$(uname -s)" in

   Darwin)
     echo 'Mac OS X'
     ;;

   Linux)
     echo 'Linux'
     ;;

   CYGWIN*|MINGW32*|MSYS*)
     echo 'MS Windows'
     ;;

   # Add here more strings to compare
   # See correspondence table at the bottom of this answer

   *)
     echo 'other OS' 
     ;;
esac

ниже Makefile is вдохновение от проект Git (config.mak.uname).

ifdef MSVC     # Avoid the MingW/Cygwin sections
    uname_S := Windows
else                          # If uname not available => 'not' 
    uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
endif

# Avoid nesting "if .. else if .. else .. endif endif"
# because maintenance of matching if/else/endif is a pain

ifeq ($(uname_S),Windows)
    CC := cl 
endif
ifeq ($(uname_S),OSF1)
    CFLAGS += -D_OSF_SOURCE
endif
ifeq ($(uname_S),Linux)
    CFLAGS += -DNDEBUG
endif
ifeq ($(uname_S),GNU/kFreeBSD)
    CFLAGS += -D_BSD_ALLOC
endif
ifeq ($(uname_S),UnixWare)
    CFLAGS += -Wextra
endif
...

см. также это полный ответ про uname -s и Makefile.

таблица соответствия в нижней части этого ответа от статья в Википедии о uname. Пожалуйста, внесите свой вклад, чтобы держать его в курсе (редактировать ответ или Оставить комментарий). Вы также можете обновить статью Википедии и оставить комментарий, чтобы заметить меня о своем вкладе MSYS MSYS_NT-6.1


Bash устанавливает переменную оболочки OSTYPE. От man bash:

автоматически установить строку, описывающую операционную систему на который Баш выполняет.

это имеет крошечное преимущество над uname в том, что он не требует запуска нового процесса, так будет быстрее выполняться.

однако я не могу найти авторитетный список ожидаемых значений. Для меня на Ubuntu 14.04 установлено значение "linux-gnu". Я поскреб паутину в поисках других ценностей. Таким образом:

case "$OSTYPE" in
  linux*)   echo "Linux / WSL" ;;
  darwin*)  echo "Mac OS" ;; 
  win*)     echo "Windows" ;;
  msys*)    echo "MSYS / MinGW / Git Bash" ;;
  cygwin*)  echo "Cygwin" ;;
  bsd*)     echo "BSD" ;;
  solaris*) echo "Solaris" ;;
  *)        echo "unknown: $OSTYPE" ;;
esac

звездочки важны в некоторых случаях - например, OSX добавляет номер версии ОС после "darwin". Значение " win "на самом деле "win32", мне сказали - может быть, есть "win64"?

возможно, мы могли бы работать вместе, чтобы заполнить таблицу проверенные значения здесь:

  • Linux Ubuntu (ВКЛ. WSL):linux-gnu
  • Cygwin 64-бит: cygwin
  • префикса msys/MinGW в (ГИТ Баш для Windows): msys

(пожалуйста, добавьте ваше значение, если оно отличается от существующих записей)


чтобы опираться на ответ Альберта, мне нравится использовать $COMSPEC для обнаружения Windows:

#!/bin/bash

if [ "$(uname)" == "Darwin" ]
then
 echo Do something under Mac OS X platform
elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]
then
  echo Do something under Linux platform
elif [ -n "$COMSPEC" -a -x "$COMSPEC" ]
then 
  echo : this script does not support Windows \:\(
fi

это позволяет избежать разбора вариантов имен Windows для $OS, и разбор вариантов uname как MINGW, Cygwin, etc.

Справочная информация: %COMSPEC% - это переменная среды Windows, указывающая полный путь к командному процессору (он же оболочка Windows). Значение этой переменной обычно %SystemRoot%\system32\cmd.exe, которые, как правило, оценивает в C:\Windows\system32\cmd.exe .


# This script fragment emits Cygwin rulez under bash/cygwin
if [[ $(uname -s) == CYGWIN* ]];then
    echo Cygwin rulez
else 
    echo Unix is king
fi

Если 6 первых символов команды uname-s - "CYGWIN", предполагается система cygwin


http://en.wikipedia.org/wiki/Uname

вся информация, которая вам когда-либо понадобится. Google - ваш друг.

использовать uname -s для запроса имени системы.

  • Mac:Darwin
  • Cygwin:CYGWIN_...
  • в Linux: различные, LINUX для большинства

хорошо, вот мой путь.

osis()
{
    local n=0
    if [[ "" = "-n" ]]; then n=1;shift; fi

    # echo $OS|grep  -i >/dev/null
    uname -s |grep -i "" >/dev/null

    return $(( $n ^ $? ))
}

например

osis Darwin &&
{
    log_debug Detect mac osx
}
osis Linux &&
{
    log_debug Detect linux
}
osis -n Cygwin &&
{
    log_debug Not Cygwin
}

Я использую это в моем dotfiles


использовать только из командной строки работает очень хорошо, спасибо Джастину:

#!/bin/bash

################################################## #########
# Bash script to find which OS
################################################## #########

OS=`uname`
echo "$OS"

источник


Я думаю, что uname ответ непобедим, в основном с точки зрения чистоты.

хотя для выполнения требуется смешное время, я обнаружил, что тестирование наличия определенных файлов также дает мне хорошие и более быстрые результаты, так как я не вызываю исполняемый файл:

и

[ -f /usr/bin/cygwin1.dll ] && echo Yep, Cygwin running

просто использует быструю проверку наличия файла Bash. Поскольку я сейчас на Windows, я не могу сказать вам никаких конкретных файлов для Linuxes и Mac OS X из моей головы, но я уверен, что они существуют. :-)