[bash] Bash 스크립트에서 OS를 감지하는 방법은 무엇입니까?

내가 사용하는 모든 컴퓨터에서 사용할 수 있도록 내 파일 .bashrc.bash_login파일을 버전 관리 상태로 유지하고 싶습니다 . 문제는 일부 OS 관련 별칭이 있으므로 스크립트가 Mac OS X, Linux 또는 Cygwin 에서 실행되고 있는지 확인하는 방법을 찾고 있다는 것 입니다.

Bash 스크립트 에서 운영 체제를 감지하는 올바른 방법은 무엇입니까 ?



답변

다음과 같이 작동한다고 생각합니다. win32그래도 확실하지 않습니다 .

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        # ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
        # Mac OSX
elif [[ "$OSTYPE" == "cygwin" ]]; then
        # POSIX compatibility layer and Linux environment emulation for Windows
elif [[ "$OSTYPE" == "msys" ]]; then
        # Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
elif [[ "$OSTYPE" == "win32" ]]; then
        # I'm not sure this can happen.
elif [[ "$OSTYPE" == "freebsd"* ]]; then
        # ...
else
        # Unknown.
fi


답변

내 .bashrc에는 다음 코드를 사용합니다.

platform='unknown'
unamestr=`uname`
if [[ "$unamestr" == 'Linux' ]]; then
   platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
   platform='freebsd'
fi

그런 다음 다음과 같은 작업을 수행합니다.

if [[ $platform == 'linux' ]]; then
   alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
   alias ls='ls -G'
fi

추악하지만 작동합니다. 원하는 경우 case대신 사용할 수 있습니다 if.


답변

bash 맨 페이지에는 변수 OSTYPE에 운영 체제 이름이 저장되어 있다고 나와 있습니다.

OSTYPEbash가 실행중인 운영 체제를 설명하는 문자열로 자동 설정됩니다. 기본값은 시스템에 따라 다릅니다.

여기로 설정되어 linux-gnu있습니다.


답변

$OSTYPE

미리 정의 된 $OSTYPE변수를 간단히 사용할 수 있습니다 . 예 :

case "$OSTYPE" in
  solaris*) echo "SOLARIS" ;;
  darwin*)  echo "OSX" ;;
  linux*)   echo "LINUX" ;;
  bsd*)     echo "BSD" ;;
  msys*)    echo "WINDOWS" ;;
  *)        echo "unknown: $OSTYPE" ;;
esac

그러나 이전 쉘 (예 : Bourne 쉘 ) 에서는 인식되지 않습니다 .


uname

또 다른 방법은 uname명령을 기반으로 플랫폼을 감지하는 것 입니다.

다음 스크립트를 참조하십시오 (.bashrc에 포함 가능).

# Detect the platform (similar to $OSTYPE)
OS="`uname`"
case $OS in
  'Linux')
    OS='Linux'
    alias ls='ls --color=auto'
    ;;
  'FreeBSD')
    OS='FreeBSD'
    alias ls='ls -G'
    ;;
  'WindowsNT')
    OS='Windows'
    ;;
  'Darwin')
    OS='Mac'
    ;;
  'SunOS')
    OS='Solaris'
    ;;
  'AIX') ;;
  *) ;;
esac

내 실제 사례를 찾을 수 있습니다.bashrc .


Travis CI에 사용 된 유사한 버전은 다음과 같습니다 .

case $(uname | tr '[:upper:]' '[:lower:]') in
  linux*)
    export TRAVIS_OS_NAME=linux
    ;;
  darwin*)
    export TRAVIS_OS_NAME=osx
    ;;
  msys*)
    export TRAVIS_OS_NAME=windows
    ;;
  *)
    export TRAVIS_OS_NAME=notset
    ;;
esac


답변

검출 운영 체제 및 CPU 타입은 너무 쉽게 할 수없는 이식 . 나는 sh매우 다양한 Unix 플랫폼에서 작동하는 약 100 줄 의 스크립트를 가지고 있습니다 : 1988 년 이래로 사용한 시스템.

핵심 요소는

  • uname -p입니다 프로세서 유형 하지만 일반적으로 unknown현대 유닉스 플랫폼에서.

  • uname -m 일부 유닉스 시스템에서 “기계 하드웨어 이름”을 제공합니다.

  • /bin/arch존재하는 경우 일반적으로 프로세서 유형을 제공합니다.

  • uname 인수가 없으면 운영 체제 이름이 지정됩니다.

결국 플랫폼 간의 차이점과 플랫폼을 얼마나 잘 만들고 싶어하는지 생각 해야합니다. 예를 들어, 단지 물건을 간단하게 유지하기 위해, 나는 치료 i386를 통해 i686, 어떤 ” Pentium*“및 ” AMD*Athlon*“모든으로 x86.

~/.profile시작시 스크립트를 실행하여 하나의 변수를 CPU와 운영 체제의 조합을 나타내는 문자열로 설정합니다. 나는 플랫폼 별이가 bin, man, lib, 및 include설정받을 디렉토리를 그 기반으로. 그런 다음 환경 변수의 보트로드를 설정했습니다. 예를 들어, 메일을 재 포맷하기위한 쉘 스크립트는 예를 들어 $LIB/mailfmt플랫폼 별 실행 바이너리 인 호출 할 수 있습니다 .

당신이 절단 된 모서리 원하는 경우 , uname -m그리고 일반은 uname당신이 많은 플랫폼에서 알고 싶은 당신에게 말할 것이다. 필요할 때 다른 것을 추가하십시오. (그리고 case중첩되지 않은를 사용하십시오 if!)


답변

이 완전한 bash 코드를 사용하는 것이 좋습니다

lowercase(){
    echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}

OS=`lowercase \`uname\``
KERNEL=`uname -r`
MACH=`uname -m`

if [ "{$OS}" == "windowsnt" ]; then
    OS=windows
elif [ "{$OS}" == "darwin" ]; then
    OS=mac
else
    OS=`uname`
    if [ "${OS}" = "SunOS" ] ; then
        OS=Solaris
        ARCH=`uname -p`
        OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
    elif [ "${OS}" = "AIX" ] ; then
        OSSTR="${OS} `oslevel` (`oslevel -r`)"
    elif [ "${OS}" = "Linux" ] ; then
        if [ -f /etc/redhat-release ] ; then
            DistroBasedOn='RedHat'
            DIST=`cat /etc/redhat-release |sed s/\ release.*//`
            PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/SuSE-release ] ; then
            DistroBasedOn='SuSe'
            PSUEDONAME=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
            REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
        elif [ -f /etc/mandrake-release ] ; then
            DistroBasedOn='Mandrake'
            PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
            REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
        elif [ -f /etc/debian_version ] ; then
            DistroBasedOn='Debian'
            DIST=`cat /etc/lsb-release | grep '^DISTRIB_ID' | awk -F=  '{ print $2 }'`
            PSUEDONAME=`cat /etc/lsb-release | grep '^DISTRIB_CODENAME' | awk -F=  '{ print $2 }'`
            REV=`cat /etc/lsb-release | grep '^DISTRIB_RELEASE' | awk -F=  '{ print $2 }'`
        fi
        if [ -f /etc/UnitedLinux-release ] ; then
            DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
        fi
        OS=`lowercase $OS`
        DistroBasedOn=`lowercase $DistroBasedOn`
        readonly OS
        readonly DIST
        readonly DistroBasedOn
        readonly PSUEDONAME
        readonly REV
        readonly KERNEL
        readonly MACH
    fi

fi

더 많은 예제 예제는 다음과 같습니다. https://github.com/coto/server-easy-install/blob/master/lib/core.sh


답변

bash에서 문서화 된대로 $OSTYPE및을 사용하십시오 $HOSTTYPE. 이것이 제가하는 것입니다. 이것으로 충분하지 않고 짝수 uname또는 uname -a다른 적절한 옵션으로 충분한 정보를 얻지 못하면 GNU 프로젝트 의 config.guess 스크립트 가 항상 이 목적을 위해 만들어졌습니다.