Jak wykryć system operacyjny ze skryptu Bash?
Chciałbym zachować moje pliki .bashrc
i .bash_login
w kontroli wersji, aby móc używać ich pomiędzy wszystkimi komputerami, z których korzystam. Problem w tym, że mam pewne aliasy specyficzne dla systemu operacyjnego, więc szukałem sposobu, aby określić, czy skrypt działa na Mac OS X, Linux lub Cygwin .
Jaki jest właściwy sposób wykrywania systemu operacyjnego w skrypcie Bash ?
21 answers
Myślę, że to powinno zadziałać. Nie jestem jednak pewien co do 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-05 12:08:57
Dla mojego .bashrc, używam następującego kodu:
platform='unknown'
unamestr=`uname`
if [[ "$unamestr" == 'Linux' ]]; then
platform='linux'
elif [[ "$unamestr" == 'FreeBSD' ]]; then
platform='freebsd'
fi
Potem robię coś takiego jak:
if [[ $platform == 'linux' ]]; then
alias ls='ls --color=auto'
elif [[ $platform == 'freebsd' ]]; then
alias ls='ls -G'
fi
Jest brzydki, ale działa. Jeśli wolisz, możesz użyć case
zamiast if
.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-27 22:37:33
Strona podręcznika bash mówi, że zmienna OSTYPE przechowuje nazwę systemu operacyjnego:
OSTYPE
automatycznie ustawia się na ciąg opisujący system operacyjny, na którym bash jest wykonywany. Domyślną wartością jest system- zależny.
Jest ustawiony na linux-gnu
tutaj. jio
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-15 18:11:31
$OSTYPE
Możesz po prostu użyć predefiniowanej zmiennej $OSTYPE
np.:
case "$OSTYPE" in
solaris*) echo "SOLARIS" ;;
darwin*) echo "OSX" ;;
linux*) echo "LINUX" ;;
bsd*) echo "BSD" ;;
msys*) echo "WINDOWS" ;;
*) echo "unknown: $OSTYPE" ;;
esac
Jednak nie są rozpoznawane przez starsze muszle (takie jak Bourne shell).
uname
Inną metodą jest wykrywanie platformy na podstawie polecenia uname
.
Patrz następujący skrypt (gotowy do włączenia w ."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
Praktyczny przykład znajdziesz w moim .bashrc
.
Oto podobna wersja użyta na 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-09 09:16:21
Wykrywanie systemu operacyjnego i typu procesora nie jest tak łatwe do zrobienia przenośnie . Mam skrypt sh
składający się z około 100 linii, który działa na bardzo różnych platformach Unix: dowolnym systemie używanym od 1988 roku.
Kluczowymi elementami są
uname -p
jest typem procesora, ale zazwyczaj jestunknown
na współczesnych platformach Unix.uname -m
poda "nazwę sprzętu komputerowego" na jakimś Uniksie systemy./bin/arch
, jeśli istnieje, zwykle podaje Typ procesora.uname
bez argumentów nazwa systemu operacyjnego.
W końcu będziesz musiał pomyśleć o rozróżnieniach między platformami i Jak Dobrze chcesz je zrobić. na przykład, dla uproszczenia, traktuję i386
przezi686
, dowolne "Pentium*
" i dowolne "AMD*Athlon*
" jako x86
.
Mój ~/.profile
uruchamia skrypt a przy starcie, który ustawia jedną zmienną na ciąg znaków wskazujący kombinację procesora i systemu operacyjnego. Mam konkretną platformębin
, man
, lib
, i include
katalogi, które są ustawiane na tej podstawie. Następnie ustawiłem boatload zmiennych środowiskowych. Na przykład skrypt powłoki do sformatowania poczty może wywołać, np. $LIB/mailfmt
, który jest plikiem wykonywalnym specyficznym dla platformy.
Jeśli chcesz wyciąć rogi, uname -m
a plain uname
powie Ci to, co chcesz wiedzieć na wielu platformach. Dodaj inne rzeczy, kiedy tego potrzebujesz. (I używać case
, nie zagnieżdżać if
!)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-26 22:51:44
Zalecam użycie tego pełnego kodu 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
echo $OS
echo $KERNEL
echo $MACH
Więcej przykładów przykłady tutaj: https://github.com/coto/server-easy-install/blob/master/lib/core.sh
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-16 19:47:44
Sugerowałbym unikanie niektórych z tych odpowiedzi. Nie zapominaj, że możesz wybrać inne formy porównywania ciągów, które wyjaśniłyby większość wariantów lub oferowany brzydki kod.
Jednym z takich rozwiązań byłaby prosta kontrola, np.:
if [[ "$OSTYPE" =~ ^darwin ]]; then
Który ma dodatkową zaletę dopasowania dowolnej wersji Darwina, pomimo jego sufiksu wersji. Działa to również dla dowolnych odmian Linux
, których można się spodziewać.
Możesz zobaczyć kilka dodatkowych przykładów w moich plikach dotfiles tutaj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-03 21:59:43
W bashu używaj $OSTYPE
i $HOSTTYPE
, zgodnie z dokumentacją; tym się zajmuję. Jeśli to nie wystarczy, a nawet uname
lub uname -a
(lub inne odpowiednie opcje) nie daje wystarczającej ilości informacji, zawsze jest config.zgadnijcie skrypt projektu GNU, zrobiony dokładnie w tym celu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-14 11:24:37
Spróbuj użyć "uname". Na przykład w Linuksie: "uname-a".
Zgodnie ze stroną podręcznika, uname jest zgodny z SVr4 i POSIX, więc powinien być dostępny również na Mac OS X i Cygwin, ale nie mogę tego potwierdzić.
BTW: $OSTYPE jest też ustawione na linux-gnu
tutaj:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-19 15:38:33
Napisałem te cukry w moim .bashrc
:
if_os () { [[ $OSTYPE == *$1* ]]; }
if_nix () {
case "$OSTYPE" in
*linux*|*hurd*|*msys*|*cygwin*|*sua*|*interix*) sys="gnu";;
*bsd*|*darwin*) sys="bsd";;
*sunos*|*solaris*|*indiana*|*illumos*|*smartos*) sys="sun";;
esac
[[ "${sys}" == "$1" ]];
}
Więc mogę robić takie rzeczy jak:
if_nix gnu && alias ls='ls --color=auto' && export LS_COLORS="..."
if_nix bsd && export CLICOLORS=on && export LSCOLORS="..."
if_os linux && alias psg="ps -FA | grep" #alternative to pgrep
if_nix bsd && alias psg="ps -alwx | grep -i" #alternative to pgrep
if_os darwin && alias finder="open -R"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 18:00:19
uname
Lub
uname -a
Jeśli chcesz więcej informacji
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-26 20:33:45
Napisałemosobistą bibliotekę Bash i Framework skryptowy , który używaGNU shtool do dość dokładnego wykrywania platformy.
GNU SHTOOL jest bardzo przenośnym zestawem skryptów, który zawiera między innymi polecenie 'shtool platform'. Oto wynik:
shtool platform -v -F "%sc (%ac) %st (%at) %sp (%ap)"
Na kilku różnych maszynach:
Mac OS X Leopard:
4.4BSD/Mach3.0 (iX86) Apple Darwin 9.6.0 (i386) Apple Mac OS X 10.5.6 (iX86)
Ubuntu Jaunty server:
LSB (iX86) GNU/Linux 2.9/2.6 (i686) Ubuntu 9.04 (iX86)
Debian Lenny:
LSB (iX86) GNU/Linux 2.7/2.6 (i686) Debian GNU/Linux 5.0 (iX86)
To daje całkiem zadowalające wyniki, jak widać. GNU shtool jest trochę powolny, więc faktycznie przechowuję i aktualizuję platformę Identyfikacja w pliku w systemie, który wywołują moje Skrypty. To mój framework, więc działa dla mnie, ale twój przebieg może się różnić.
Teraz będziesz musiał znaleźć sposób, aby spakować shtool ze swoimi skryptami, ale to nie jest trudne ćwiczenie. Zawsze możesz wrócić na wyjście uname.
EDIT:
Przegapiłem post misia o config.guess
(jakoś). Są to bardzo podobne Skrypty, ale nie te same. Osobiście używam shtool również do innych zastosowań i działa całkiem dobrze dla mnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-19 15:41:42
Możesz użyć:
OS=$(uname -s)
Następnie możesz użyć zmiennej OS w swoim skrypcie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-23 11:42:13
To powinno być bezpieczne w użyciu na wszystkich dystrybucjach.
$ cat /etc/*release
To produkuje coś takiego.
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=17
DISTRIB_CODENAME=qiana
DISTRIB_DESCRIPTION="Linux Mint 17 Qiana"
NAME="Ubuntu"
VERSION="14.04.1 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.1 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
Wyodrębnij / Przypisz do zmiennych zgodnie z życzeniem
Uwaga: na niektórych ustawieniach. Może to również spowodować błędy, które można zignorować.
cat: /etc/upstream-release: Is a directory
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-21 01:10:35
Poniżej znajduje się podejście do wykrywania bazujących na Debianie i Redhacie Linux OS wykorzystujących/etc / LSB-release oraz /etc / os-release (w zależności od używanego Linuksa) i podjąć prostą akcję na jego podstawie.
#!/bin/bash
set -e
YUM_PACKAGE_NAME="python python-devl python-pip openssl-devel"
DEB_PACKAGE_NAME="python2.7 python-dev python-pip libssl-dev"
if cat /etc/*release | grep ^NAME | grep CentOS; then
echo "==============================================="
echo "Installing packages $YUM_PACKAGE_NAME on CentOS"
echo "==============================================="
yum install -y $YUM_PACKAGE_NAME
elif cat /etc/*release | grep ^NAME | grep Red; then
echo "==============================================="
echo "Installing packages $YUM_PACKAGE_NAME on RedHat"
echo "==============================================="
yum install -y $YUM_PACKAGE_NAME
elif cat /etc/*release | grep ^NAME | grep Fedora; then
echo "================================================"
echo "Installing packages $YUM_PACKAGE_NAME on Fedorea"
echo "================================================"
yum install -y $YUM_PACKAGE_NAME
elif cat /etc/*release | grep ^NAME | grep Ubuntu; then
echo "==============================================="
echo "Installing packages $DEB_PACKAGE_NAME on Ubuntu"
echo "==============================================="
apt-get update
apt-get install -y $DEB_PACKAGE_NAME
elif cat /etc/*release | grep ^NAME | grep Debian ; then
echo "==============================================="
echo "Installing packages $DEB_PACKAGE_NAME on Debian"
echo "==============================================="
apt-get update
apt-get install -y $DEB_PACKAGE_NAME
elif cat /etc/*release | grep ^NAME | grep Mint ; then
echo "============================================="
echo "Installing packages $DEB_PACKAGE_NAME on Mint"
echo "============================================="
apt-get update
apt-get install -y $DEB_PACKAGE_NAME
elif cat /etc/*release | grep ^NAME | grep Knoppix ; then
echo "================================================="
echo "Installing packages $DEB_PACKAGE_NAME on Kanoppix"
echo "================================================="
apt-get update
apt-get install -y $DEB_PACKAGE_NAME
else
echo "OS NOT DETECTED, couldn't install package $PACKAGE"
exit 1;
fi
exit 0
Przykład Wyjścia dla Ubuntu Linux:
delivery@delivery-E5450$ sudo sh detect_os.sh
[sudo] password for delivery:
NAME="Ubuntu"
===============================================
Installing packages python2.7 python-dev python-pip libssl-dev on Ubuntu
===============================================
Ign http://dl.google.com stable InRelease
Get:1 http://dl.google.com stable Release.gpg [916 B]
Get:2 http://dl.google.com stable Release [1.189 B]
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-20 12:36:45
Spróbuj tego:
DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-08 10:04:54
Możesz użyć następującej klauzuli if I rozwinąć ją w razie potrzeby:
if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
aminute_ago="-v-1M"
elif [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
aminute_ago="-d \"1 minute ago\""
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-30 04:19:30
Zachowuję swoje .bashrc i .bash_alias na współdzielenie plików, do których mają dostęp wszystkie platformy. W ten sposób pokonuję problem w moim .bash_alias:
if [[ -f (name of share)/.bash_alias_$(uname) ]]; then
. (name of share)/.bash_alias_$(uname)
fi
I mam na przykład a .bash_alias_Linux with:
alias ls='ls --color=auto'
W ten sposób zachowam oddzielny kod specyficzny dla platformy i przenośny, możesz zrobić to samo .bashrc
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-15 17:36:42
Wypróbowałem powyższe wiadomości w kilku dystrybucjach Linuksa i okazało się, że poniższe działają najlepiej dla mnie. Jest to krótka, zwięzła, dokładna odpowiedź słowa, która działa również w Bash w systemie Windows.
OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-09 18:55:48
To sprawdza kilka plików known
do identyfikowania, jeśli dystrybucja Linuksa to Debian lub Ubunu, to domyślnie jest to zmienna $OSTYPE
.
os='Uknown'
unamestr="${OSTYPE//[0-9.]/}"
os=$( compgen -G "/etc/*release" > /dev/null && cat /etc/*release | grep ^NAME | tr -d 'NAME="' || echo "$unamestr")
echo "$os"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 19:24:42
Wykonanie następujących czynności pomogło w poprawnym sprawdzeniu ubuntu:
if [[ "$OSTYPE" =~ ^linux ]]; then
sudo apt-get install <some-package>
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-21 01:53:56