Как определить ОС из скрипта Bash? - PullRequest
428 голосов
/ 26 декабря 2008

Я хотел бы сохранить свои файлы .bashrc и .bash_login в системе контроля версий, чтобы их можно было использовать между всеми компьютерами, которые я использую. Проблема в том, что у меня есть некоторые псевдонимы для ОС, поэтому я искал способ определить, работает ли скрипт в Mac OS X, Linux или Cygwin .

Как правильно определить операционную систему в сценарии Bash ?

Ответы [ 21 ]

7 голосов
/ 23 ноября 2017

Вы можете использовать следующее:

OS=$(uname -s)

тогда вы можете использовать переменную ОС в вашем скрипте.

7 голосов
/ 26 декабря 2008
uname

или

uname -a

если вы хотите больше информации

7 голосов
/ 12 марта 2009

Я написал личную библиотеку Bash и среду сценариев , которая использует GNU shtool для довольно точного определения платформы.

GNU shtool - это очень переносимый набор скриптов, который содержит, среди прочего, команду 'shtool platform'. Вот вывод:

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

на нескольких разных машинах:

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)

Это дает довольно удовлетворительные результаты, как вы можете видеть. GNU shtool немного медленный, поэтому я на самом деле храню и обновляю идентификацию платформы в файле в системе, который вызывают мои скрипты. Это мой каркас, так что он работает для меня, но ваш пробег может отличаться.

Теперь вам нужно найти способ упаковки shtool с вашими скриптами, но это не сложное упражнение. Вы также всегда можете воспользоваться выводом uname.

EDIT:

Я пропустил пост Тедди о config.guess (как-то). Это очень похожие сценарии, но не одинаковые. Лично я использую shtool и для других целей, и он работал довольно хорошо для меня.

5 голосов
/ 20 января 2017

Ниже представлен подход к обнаружению на основе Debian и RedHat ОС Linux с использованием / etc / lsb-release и / etc / os-release (в зависимости от используемого вами варианта Linux) и на его основе выполните простое действие.

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

Пример вывода для 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] 
...            
5 голосов
/ 21 августа 2014

Это должно быть безопасно для использования на всех дистрибутивах.

$ cat /etc/*release

Это производит что-то вроде этого.

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

Извлечение / присвоение переменных по вашему желанию

Примечание: на некоторых установках. Это также может привести к ошибкам, которые вы можете игнорировать.

     cat: /etc/upstream-release: Is a directory
2 голосов
/ 28 февраля 2016

Вы можете использовать следующее условие if и расширить его при необходимости:

if [ "${OSTYPE//[0-9.]/}" == "darwin" ]
then
    aminute_ago="-v-1M"
elif  [ "${OSTYPE//[0-9.]/}" == "linux-gnu" ]
then
    aminute_ago="-d \"1 minute ago\""
fi
1 голос
/ 15 января 2015

Я склонен хранить мои .bashrc и .bash_alias в общей папке, к которой имеют доступ все платформы. Вот как я побеждаю проблему в моем .bash_alias:

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

И у меня есть, например, .bash_alias_Linux с:

alias ls='ls --color=auto'

Таким образом, я разделяю платформу и переносимый код, вы можете сделать то же самое для .bashrc

0 голосов
/ 08 марта 2017

Я попробовал описанные выше сообщения в нескольких дистрибутивах Linux и обнаружил, что для меня лучше всего подойдет следующее. Это короткое и точное слово-ответ, которое подходит и для Bash в Windows.

OS=$(cat /etc/*release | grep ^NAME | tr -d 'NAME="') #$ echo $OS # Ubuntu
0 голосов
/ 02 октября 2018

Это проверяет кучу файлов known, чтобы определить, является ли дистрибутив linux Debian или Ubunu, тогда по умолчанию используется переменная $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"
0 голосов
/ 08 ноября 2018

попробуйте это:

DISTRO=$(cat /etc/*-release | grep -w NAME | cut -d= -f2 | tr -d '"')
echo "Determined platform: $DISTRO"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...