Wie erkenne ich das Betriebssystem anhand eines Bash-Skripts?

525

Ich möchte meine .bashrcund .bash_loginDateien in der Versionskontrolle behalten, damit ich sie zwischen allen von mir verwendeten Computern verwenden kann. Das Problem ist, dass ich einige betriebssystemspezifische Aliase habe und daher nach einer Möglichkeit gesucht habe, festzustellen, ob das Skript unter Mac OS X, Linux oder Cygwin ausgeführt wird .

Was ist der richtige Weg, um das Betriebssystem in einem Bash- Skript zu erkennen?

csexton
quelle
1
Haben Sie jemals darüber nachgedacht, Ihre Konfigurationen zu teilen? Ich wollte die gleiche Art von Setup bekommen :)
Sorin
@sorin Ich weiß, dass es ein alter Kommentar ist, aber wenn Sie immer noch neugierig sind, habe ich ProfileGem erstellt, mit dem Sie steckbare Bash-Umgebungen für alle Ihre Computer konfigurieren können.
dimo414
1
@ dimo414 profilegem scheint hierher verschoben worden zu sein bitbucket.org/dimo414/profilegem . Probieren Sie einige dieser Dotfiles-Projekte aus, um Bash-Konfigurationen im Allgemeinen zu teilen: github.com/…
Mahemoff
1
@ Mahemoff danke für den aktualisierten Link, sorry, ich kann meinen Kommentar nicht bearbeiten. Ich würde mich über Feedback oder Fehler freuen, wenn Sie mit ProfileGem experimentieren!
dimo414
Leider lehnt BitBucket die Mercurial-Unterstützung ab, daher muss ich meinen Link erneut aktualisieren :( github.com/dimo414/ProfileGem ist das neue Zuhause.
dimo414

Antworten:

521

Ich denke, das Folgende sollte funktionieren. Ich bin mir win32allerdings nicht sicher .

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
Timmmm
quelle
7
Unter Windows erhalten Sie msysfür Git Bash / msysGit und cygwinfür Cygwin
friederbluemle
1
Diese Antwort, einschließlich der Erkennung für Windows, ist gut. Ich benutze auch Mingw32 und es kommt alsmsys
d48
2
Interessant .. Mac OSX würde immer noch "Darwin" geben.
Jonathanbell
6
Etwas, das mich auslöste, wenn Sie den Kommentar durch einen Befehl ersetzen - stellen Sie sicher, dass Sie mit enden ;.
Vadim Peretokin
1
Wenn ich einen Befehl wie hinzufüge source somefile ; , bekomme ich syntax error near unexpected token elif.
Oarfish
292

Für meine .bashrc verwende ich den folgenden Code:

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

Dann mache ich etwas wie:

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

Es ist hässlich, aber es funktioniert. Sie können caseanstelle von verwenden, ifwenn Sie es vorziehen.

Nicolas Martyanoff
quelle
6
Warum setzen Sie die Plattform von unamestr aus, anstatt nur unamestr zu verwenden?
Csexton
80
Verwenden Sie keine Backticks, sondern die neuere, klarere Syntax: "unamestr = $ (uname)".
Entspannen Sie am
15
Auf den ersten Blick könnten die Backticks einer Schnur ähneln.
Harrison Powers
29
@ David-Winiecki Denn wenn Sie Befehle verschachteln müssen, zB $ (Befehl-1 $ (Befehl-2))
Michael Barton
4
Wäre es nicht viel besser zu tun: platform="$(uname | tr '[:upper:]' '[:lower:]')"und dann definitiv in einem Fall zu behandeln? Es scheint nur seltsam, eine Abhängigkeit von einer ganz bestimmten Ausgabe fest zu codieren.
Brandon Buck
274

Die Bash-Manpage besagt, dass die Variable OSTYPE den Namen des Betriebssystems speichert:

OSTYPEWird automatisch auf eine Zeichenfolge festgelegt, die das Betriebssystem beschreibt, auf dem Bash ausgeführt wird. Die Standardeinstellung ist systemabhängig.

Es ist linux-gnuhier eingestellt.

Johannes Schaub - litb
quelle
5
Außerdem ist $ OSTYPE auf meinem Mac (leopard) 'darwin9.0' und unter Cygwin 'cygwin'.
dF.
5
$ OSTYPE ist darwin10.0 auf SnowLeopard. WTF mit der angehängten Version? Bedeutet, dass eine einfache case-Anweisung nicht funktioniert.
mxcl
16
Es ist keine große Sache, es zu entfernen:os=${OSTYPE//[0-9.]/}
ABach
86
case $OSTYPE in darwin*) echo I am a Mac ;; esac
Tripleee
36
@tripleee oder für Leute, die mit "wenn" if [[ $OSTYPE == darwin* ]]; then echo I am a Mac;fi
-Syntax
158

$OSTYPE

Sie können einfach eine vordefinierte $OSTYPEVariable verwenden, z.

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

Es wird jedoch von den älteren Muscheln (wie der Bourne-Muschel ) nicht erkannt .


uname

Eine andere Methode besteht darin, eine Plattform basierend auf zu erkennen uname Befehl .

Siehe das folgende Skript (bereit, in .bashrc aufgenommen zu werden):

# 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

Ein praktisches Beispiel finden Sie in meinem.bashrc .


Hier ist eine ähnliche Version, die auf Travis CI verwendet wird :

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
Kenorb
quelle
1
Bei der $ OSTYPE-Prüfung fehlt ein Zweig für Cygwin, der auf einen Windows-Computer hinweist. Die Uname-Prüfung würde auch nicht ordnungsgemäß funktionieren, wenn Cygwin Uname "CYGWIN_NT-10.0" und MinGW Uname "MINGW64_NT-10.0" zurückgibt.
Matt Pennington
1
alias ls = '/ bin / ls -G' ist eigentlich die sichere Option, im Zusammenhang mit der OS-basierten Schwuchteln sehen superuser.com/a/1299969/84662
Andrei Neculau
Ich schlage vor uname, Oracle hat Konventionen beschönigt und eine kostenlose Versionszeichenfolge mit ihren eingefügt OSTYPE ==> solaris2.11. unameist etwas sauberer und weniger Arbeit zu erledigen.
wird
37

Das Erkennen von Betriebssystem und CPU-Typ ist nicht so einfach portabel . Ich habe ein shSkript mit ungefähr 100 Zeilen, das auf einer Vielzahl von Unix-Plattformen funktioniert: jedes System, das ich seit 1988 verwende.

Die Schlüsselelemente sind

  • uname -pist ein Prozessortyp , befindet sich jedoch normalerweise unknownauf modernen Unix-Plattformen.

  • uname -m gibt auf einigen Unix-Systemen den "Namen der Maschinenhardware" an.

  • /bin/arch, falls vorhanden, gibt normalerweise den Prozessortyp an.

  • uname Ohne Argumente wird das Betriebssystem benannt.

Schließlich müssen Sie über die Unterschiede zwischen Plattformen nachdenken und darüber, wie gut Sie sie machen möchten. Zum Beispiel, nur die Dinge einfach zu halten, behandeln ich i386durch i686jede „ Pentium*“ und alle „ AMD*Athlon*“ alle alsx86 .

My ~/.profileführt beim Start ein Skript aus, das eine Variable auf eine Zeichenfolge setzt, die die Kombination von CPU und Betriebssystem angibt. Ich habe plattformspezifische bin, man, lib, und includeVerzeichnisse , die auf das gesetzt bekommen basiert. Dann habe ich eine Schiffsladung Umgebungsvariablen gesetzt. So kann beispielsweise ein Shell-Skript zum Neuformatieren von E-Mails z.$LIB/mailfmt eine plattformspezifische ausführbare Binärdatei.

Wenn Sie schneiden Ecken wollen , uname -mund Ebene unamewird Ihnen sagen , was Sie auf vielen Plattformen wissen wollen. Fügen Sie andere Dinge hinzu, wenn Sie es brauchen. (Und verwenden case, nicht verschachtelt if!)

Norman Ramsey
quelle
2
Laut uname Command entspricht uname ohne Parameter der Verwendung des Parameters "-s": "-s Zeigt den Systemnamen an. Dieses Flag ist standardmäßig aktiviert." Um explizit zu sein, könnte man "uname -s" anstelle von "uname" verwenden. (Etwas ausgearbeitet in einer Antwort auf 'Shell Output Help' )
Peter Mortensen
Haben Sie einen Link zu einem Github-Git oder Pastebin mit diesem 100-Skript, um die Betriebssystem- und Prozessorarchitektur zuverlässig zu erkennen?
Andrew De Andrade
4
@ AndrewDeAndrade Ich schäme mich, diesen Code der Öffentlichkeit zugänglich zu machen. pastebin.com/J66Lj6wf
Norman Ramsey
Wie wäre es uname -s?
Alexander Mills
35

Ich empfehle, diesen vollständigen Bash-Code zu verwenden

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

Weitere Beispiele hier: https://github.com/coto/server-easy-install/blob/master/lib/core.sh

coto
quelle
1
Sie haben die Kleinbuchstabenfunktion weggelassen, ich habe Ihre Antwort für Sie aktualisiert.
Robin Clowers
1
Sobald Sie wissen, dass es sich um Linux handelt, scheint es am einfachsten zu sein, nur ls /etcnach "blah-release" zu suchen - was auch immer blah ist, das ist das Linux-Betriebssystem - CentOS, Ubuntu , etc
Chris Moschini
1
Ich habe bearbeitet, weil einige der Verweise auf OS-Variablen als "{$ OS}" geschrieben wurden. Ich habe sie in "$ {OS}" geändert. Das ist der richtige Weg. Ich habe es getestet
Bazz
Würden Sie in Betracht ziehen, "echo $ {OS}" ganz am Ende des Skripts hinzuzufügen?
Oleg Kokorin
10

Verwenden Sie in bash $OSTYPEund $HOSTTYPE, wie dokumentiert; das ist was ich mache. Wenn dies nicht ausreicht und gerade unameoder uname -a(oder andere geeignete Optionen) nicht genügend Informationen liefern, gibt es immer das Skript config.guess aus dem GNU-Projekt, das genau für diesen Zweck erstellt wurde.

Teddy
quelle
10

Ich würde vorschlagen, einige dieser Antworten zu vermeiden. Vergessen Sie nicht, dass Sie andere Formen des Zeichenfolgenvergleichs auswählen können, um die meisten Variationen oder den angebotenen hässlichen Code zu beseitigen.

Eine solche Lösung wäre eine einfache Überprüfung, wie zum Beispiel:

if [[ "$OSTYPE" =~ ^darwin ]]; then

Dies hat den zusätzlichen Vorteil, dass jede Version von Darwin trotz des Versionssuffixes übereinstimmt. Dies funktioniert auch für alle Variationen vonLinux man erwarten kann.

Sie können einige zusätzliche Beispiele in meinen Punktedateien hier sehen

Akiva
quelle
9

Versuchen Sie es mit "uname". Zum Beispiel unter Linux: "uname -a".

Laut der Handbuchseite entspricht uname SVr4 und POSIX, daher sollte es unter Mac OS X und Cygwin verfügbar sein , aber das kann ich nicht bestätigen.

Übrigens: $ OSTYPE ist auch linux-gnuhier eingestellt :)

Joao da Silva
quelle
Uname druckt ohne Parameter 'Darwin' unter Mac OS X (Leopard). Mit -a werden viele zusätzliche Informationen gedruckt (Kernel-Version, Architektur und etwas anderes, das ich nicht entziffern kann). Ich kann nicht auf Cygwin testen
David Rodríguez - Dribeas
8

Ich schrieb diese Zucker in meine .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" ]];
}

So kann ich Sachen machen wie:

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"
kfix
quelle
Übrigens funktionieren diese 9 Zeilen auf jedem Bash, der auf fast allem läuft. Keine Shellouts und funktioniert mit fast jeder Art von persönlichem .bashrc (große verschachtelte if / case-Bäume oder viele zufällige Aliase). IMO, schlägt die Hose aus jeder Antwort darüber.
kfix
Bisher am nächsten zu vervollständigen für die Aufnahme von Cygwin und anderen BSD (im Grunde Zusammenstellung der beliebten * NIX)
HidekiAI
Vervollständigen Sie für Userlands, die heute relevant sind, und führen Sie Bash aus. AIX / HP-UX / IRIX / OpenVMS-Benutzer könnten sich einschalten. Das neue Windows-Subsystem für Linux führt eine Standard-amd64-Ubuntu-Installation aus, sodass für beide if_nix gnu& true zurückgegeben werden sollte if_os linux.
Kfix
1
@kfix ja das stimmt, das win 10 bash Subsystem gibt "linux-gnu" für aus echo $OSTYPE. Um das Win 10 Bash-Subsystem spezifisch zu erkennen, war die einzige Lösung, die ich gefunden habe, nach "Microsoft" in/proc/sys/kernel/osrelease
Jpnh
7
uname

oder

uname -a

Wenn Sie weitere Informationen wünschen

Federico A. Ramponi
quelle
7

Ich habe eine persönliche Bash-Bibliothek und ein Scripting-Framework geschrieben , das GNU shtool verwendet , um eine ziemlich genaue Plattformerkennung .

GNU shtool ist ein sehr portabler Satz von Skripten, der unter anderem den Befehl 'shtool platform' enthält. Hier ist die Ausgabe von:

shtool platform -v -F "%sc (%ac) %st (%at) %sp (%ap)"

auf einigen verschiedenen Maschinen:

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)

Dies führt zu ziemlich zufriedenstellenden Ergebnissen, wie Sie sehen können. GNU shtool ist etwas langsam, daher speichere und aktualisiere ich die Plattformidentifikation tatsächlich in einer Datei auf dem System, das meine Skripte aufrufen. Es ist mein Rahmen, so dass es für mich funktioniert, aber Ihr Kilometerstand kann variieren.

Jetzt müssen Sie einen Weg finden, shtool mit Ihren Skripten zu verpacken, aber es ist keine schwierige Übung. Sie können auch jederzeit auf die Ausgabe ohne Namen zurückgreifen.

BEARBEITEN:

Ich habe den Beitrag von Teddy über config.guess(irgendwie) verpasst . Dies sind sehr ähnliche Skripte, aber nicht die gleichen. Ich persönlich benutze shtool auch für andere Zwecke und es hat für mich ganz gut funktioniert.

Waffen
quelle
7

Sie können Folgendes verwenden:

OS=$(uname -s)

Dann können Sie die Betriebssystemvariable in Ihrem Skript verwenden.

Chetan kapoor
quelle
Kannst du erklären, wie uname -ses anders ist als uname?
Alexander Mills
@ AlexanderMills -s, - Kernel-Name drucken Sie den Kernel-Namen
Chetan Kapoor
6

Im Folgenden finden Sie einen Ansatz zum Erkennen von Debian- und RedHat-basierten Linux-Betriebssystemen unter Verwendung von / etc / lsb-release und / etc / os-release (abhängig von der verwendeten Linux -Version ) und zum Ausführen einer einfachen darauf basierenden Aktion.

#!/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

Ausgabebeispiel für 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] 
...            
Exequiel Barrirero
quelle
5

Dies sollte in allen Distributionen sicher sein.

$ cat /etc/*release

Dies erzeugt so etwas.

     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/"

Extrahieren / Zuweisen von Variablen nach Ihren Wünschen

Hinweis: Bei einigen Setups. Dies kann auch zu Fehlern führen, die Sie ignorieren können.

     cat: /etc/upstream-release: Is a directory
RJ
quelle
Hinweis: Unter CentOS gibt dies[user@host ~]$ cat /etc/*release CentOS release 6.4 (Final) CentOS release 6.4 (Final) CentOS release 6.4 (Final)
cfstras
Ja, die Ausgabe, die ich gepostet habe, war ein Beispiel von einem meiner Laptops, nicht statischer Inhalt, den Sie überall sehen.
RJ
Ich habe gerade hinzugefügt, dass niemand denken würde, dass das Ergebnis immer in der gleichen Form ist :)
cfstras
1
+1 Ich verwende set -e am Anfang des Skripts (daher funktioniert diese Lösung nicht unter doxer.org/linux-shell-centos-debian-ostype ). Und andere Lösungen sind nicht speziell CentOS. Aber ich fand diese Referenz, die diese Antwort unix.stackexchange.com/a/92212
gihanchanuka
4
funktioniert nicht für Mac:cat: /etc/*release: No such file or directory
Eridal
3

Versuche dies:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"
Alexander Nekrasov
quelle
Unter macOS bekomme ichcat: /etc/*-release: No such file or directory
csexton
@csexton wirklich, ich bekomme das gleiche: zsh: no matches found: /etc/*release- das wird nur für Linux-Systeme funktionieren, nehme ich an ...
Alexander Nekrasov
Diese Antwort funktioniert sicher nur unter Linux. Andere Antworten können Linux jedoch nur im Gegensatz zu anderen Systemen erkennen. Diese grundlegende Entdeckung hilft überhaupt nicht dabei, eine bestimmte Linux-Distribution zu entdecken, die genauso wichtig ist wie die Unterscheidung zwischen FreeBSD und Darwin.
Thomas Urban
3

Sie können die folgende if-Klausel verwenden und nach Bedarf erweitern:

if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
    aminute_ago="-v-1M"
elif  [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
    aminute_ago="-d \"1 minute ago\""
fi
Tahsin Turkoz
quelle
2

Ich habe die oben genannten Meldungen in einigen Linux-Distributionen ausprobiert und festgestellt, dass Folgendes für mich am besten funktioniert. Es ist eine kurze, präzise Wortantwort, die auch für Bash unter Windows funktioniert.

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu
Intellilogic
quelle
2
Während dieser Code - Schnipsel zu begrüßen ist, und etwas Hilfe bieten kann, würde es erheblich verbessert , wenn es eine Erklärung enthalten von , wie und warum Dies löst das Problem. Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt! Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, und geben Sie an, welche Einschränkungen und Annahmen gelten.
Toby Speight
1
Scheint für die meisten Linux-Systeme nett und knapp zu sein, aber leider führt dies unter macOS zu einem Fehler. Vielleicht ist dies mehr „den Geschmack Linux - Distribution von Bash zu erkennen
csexton
1
@csexton OS=$( ([[ -f /etc/*release ]] && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || echo "Unknown" )dies funktioniert ohne Fehler zu werfen.
Kuzeko
Eigentlich ist hier ein richtiger WegOS=$( $(compgen -G "/etc/*release" > /dev/null) && cat /etc/*release | grep ^NAME | tr -d 'NAME="') || $( echo "${OSTYPE//[0-9.]/}")
Kuzeko
@ Kuzeko Ich bekomme leider immer noch Fehler beim Ausführen unter MacOS.
Csexton
1

Ich neige dazu, meine .bashrc- und .bash_alias-Dateien auf einer Dateifreigabe zu belassen, auf die alle Plattformen zugreifen können. So überwinde ich das Problem in meinen .bash_alias:

if [[ -f (name of share)/.bash_alias_$(uname) ]]; then
    . (name of share)/.bash_alias_$(uname)
fi

Und ich habe zum Beispiel eine .bash_alias_Linux mit:

alias ls='ls --color=auto'

Auf diese Weise halte ich plattformspezifischen und portablen Code getrennt. Sie können dasselbe für .bashrc tun

Ericcurtin
quelle
1

Dies überprüft eine Reihe von knownDateien auf Identifikation, wenn die Linux-Distribution Debian oder Ubunu ist, dann wird standardmäßig die $OSTYPEVariable verwendet.

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"
Kuzeko
quelle
-1

Wenn Sie Folgendes tun, können Sie die Prüfung für Ubuntu korrekt durchführen:

if [[ "$OSTYPE" =~ ^linux ]]; then
    sudo apt-get install <some-package>
fi
Sandmann
quelle
4
Was ist mit anderen Linux-Systemen, die apt-get nicht verwenden?
Wilf
Ubuntu ist eine Distribution, keine Betriebssystemklasse.
Jitter