Как узнать, работает ли платформа Ubuntu или CentOS с помощью скрипта Bash?

39

Я знаю команды для проверки имени машины Linux, работающей на моей машине. Например:

Ubuntu

cat /etc/version

CentOS

cat /etc/issue

Как мне получить выходные данные от терминала и сравнить, чтобы увидеть, является ли это UBUNTU или CENTOS и выполнить следующие команды?

apt-get install updates 

или

yum update

Ubuntu 14.04

cat /etc/issue
Шекхар
источник
2
Добро пожаловать в Спросите Ubuntu. Пожалуйста, не могли бы вы уделить
Сильвен Пино

Ответы:

53

К сожалению, нет верного, простого способа получить название дистрибутива. Большинство крупных дистрибутивов движутся к системе, где они используют /etc/os-releaseдля хранения этой информации. Большинство современных дистрибутивов также включают lsb_releaseинструменты, но они не всегда устанавливаются по умолчанию. Итак, вот несколько подходов, которые вы можете использовать:

  1. использование /etc/os-release

    awk -F= '/^NAME/{print $2}' /etc/os-release
  2. Используйте lsb_releaseинструменты, если они доступны

    lsb_release -d | awk -F"\t" '{print $2}'
  3. Используйте более сложный скрипт, который должен работать для большинства дистрибутивов:

    # Determine OS platform
    UNAME=$(uname | tr "[:upper:]" "[:lower:]")
    # If Linux, try to determine specific distribution
    if [ "$UNAME" == "linux" ]; then
        # If available, use LSB to identify distribution
        if [ -f /etc/lsb-release -o -d /etc/lsb-release.d ]; then
            export DISTRO=$(lsb_release -i | cut -d: -f2 | sed s/'^\t'//)
        # Otherwise, use release info file
        else
            export DISTRO=$(ls -d /etc/[A-Za-z]*[_-][rv]e[lr]* | grep -v "lsb" | cut -d'/' -f3 | cut -d'-' -f1 | cut -d'_' -f1)
        fi
    fi
    # For everything else (or if above failed), just use generic identifier
    [ "$DISTRO" == "" ] && export DISTRO=$UNAME
    unset UNAME
  4. Разобрать информацию о версии, gccесли установлена:

    CentOS 5.x

    $ gcc --version
    gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
    Copyright (C) 2006 Free Software Foundation, Inc.

    CentOS 6.x

    $ gcc --version
    gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)
    Copyright (C) 2010 Free Software Foundation, Inc.

    Ubuntu 12.04

    $ gcc --version
    gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
    Copyright (C) 2011 Free Software Foundation, Inc.

    Ubuntu 14.04

    $ gcc --version
    gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Это было в основном скопировано из отличного ответа @ slm на мой вопрос здесь .

Тердон
источник
«К сожалению, нет верного, простого способа получить название дистрибутива». <— Это совсем не так. Сильвен Пино , например, продемонстрировал тривиальную однострочную строку, надежно опрашивающую текущий тип платформы путем переноса на Python - который предустановлен на большинстве платформ (включая Ubuntu). Сценарии оболочки никогда не должны пытаться вручную запрашивать метаданные платформы с помощью низкоуровневых непереносимых тестов, подобных тем, которые реализованы в этом ответе.
Сесил Карри
Gawk не установлен в Debian по умолчанию.
Вилле Лайтила
@ VilleLaitila Боюсь, что это не имеет отношения здесь, так как этот сайт посвящен только Ubuntu. Но нет ничего простак конкретным здесь, так awkили mawkили ау другой реализации будет работать так же хорошо.
Terdon
Еще более конкретно, используя lsb_release:lsb_release -d | awk -F"\t" '{print $2}' | awk -F " " '{print $1}'
NerdOfCode
@NerdOfCode, если вы просто хотите получить номер релиза, делайте lsb_release -d | awk '{print $3}'или grep -oP 'VERSION="\K\S+' /etc/os-release, нет необходимости в двойном канале для awk.
Тердон
25

Вам не нужен bash для выполнения такой задачи, и я бы предложил использовать высокоуровневый подход, чтобы избежать работы с файлами типа /etc/versionи /etc/issue(у меня нет / etc / version в 13.10).

Поэтому я рекомендую использовать эту команду вместо:

python -mplatform | grep -qi Ubuntu && sudo apt-get update || sudo yum update

Модуль платформы python будет работать в обеих системах, остальная часть команды проверит, вернул ли Ubuntu python и запустил ли он apt-getеще yum.

Сильвен Пино
источник
добавить -iв grepможет помочь.
Coanor
8

Вот простой ответ, который я нахожу работающим во всех версиях Ubuntu / CentOS / RHEL простым присутствием файлов (конечно, не безотказно, если кто-то случайно выбрасывает / etc / redhat-release на ваши коробки Ubuntu и т. Д.):

if [ -f /etc/redhat-release ]; then
  yum update
fi

if [ -f /etc/lsb-release ]; then
  apt-get update
fi
Адам
источник
на моем Ubuntu нет / etc / lsb-release
noonex
3
Я не собираюсь -1, но этот ответ не является правильным по крайней мере в одном случае: /etc/lsb-releaseсуществует в CloudLinux (CentOS) 6.8, поэтому он будет возвращать yumи apt-get.
дхаупин
5

Используйте Chef для этих задач. ;-)

В Chef вы можете использовать platform?метод:

if platform?("redhat", "centos", "fedora")
  # Code for only Red Hat Linux family systems.
end

Или:

if platform?("ubuntu")
  # Code for only Ubuntu systems
end

Или:

if platform?("ubuntu")
  # Do Ubuntu things
end

Или:

if platform?("freebsd", "openbsd")
  # Do BSD things
end
user1323
источник
1
В то время как явно превосходят оболочки ориентированных хрупкие не-решений низкого уровня (например, lsb_release, /etc/os-release), это решение имеет отчетливый недостаток , что требует Chef - тяжеловес инфраструктуры как код (IAC) рамок не устанавливается по умолчанию на большинстве платформ и требующие использования свой собственный предметно-ориентированный язык (DSL). Короче говоря, большинство пользователей , вероятно , просто хотят перенести на Python , который будет установлен по умолчанию на большинстве платформ (включая Ubuntu) и интерфейсы также с помощью сценариев оболочки.
Сесил Карри
5

Проверьте Ubuntu в имени ядра:

if [  -n "$(uname -a | grep Ubuntu)" ]; then
    sudo apt-get update && sudo apt-get upgrade 
else
    yum update
fi  
Харрис
источник
4
 apt-get -v &> /dev/null && apt-get update
 which yum &> /dev/null && yum update

если есть только два дистрибутива, то вы можете сделать его короче:

apt-get -v &> /dev/null && apt-get update || yum update

каким-то образом yum -vвернуть ненулевое значение в CentOS, поэтому используйте whichвместо этого,
конечно, вы должны рассмотреть сценарий, если он не whichустановлен.

Чанг Лэнд
источник
2

Следующий скрипт должен сказать, если это Ubuntu. Если это не так, и единственный другой вариант, который у вас есть, это CentOS, вы должны указать его в elseпредложении:

dist=`grep DISTRIB_ID /etc/*-release | awk -F '=' '{print $2}'`

if [ "$dist" == "Ubuntu" ]; then
  echo "ubuntu"
else
  echo "not ubuntu"
fi
Jobin
источник
1
Вероятно, это можно упростить с помощью lsb_releaseинструмента, который должен считывать одни и те же файлы. lsb_release -iсообщает Distributor ID: Ubuntuили Distributor ID: CentOSв этих случаях.
хронит
@chronitis: да, конечно, это может быть
Jobin
Я не думаю, что он доступен по умолчанию на Centos
Sylvain Pineau
1

Выполнить /etc/os-releaseв вложенной оболочке и повторить его значение:

if [ "$(. /etc/os-release; echo $NAME)" = "Ubuntu" ]; then
  apt-get install updates 
else
  yum update
fi
jobwat
источник
0

Я бы использовал питон

if ! python -c "exec(\"import platform\nexit ('centos' not in platform.linux_distribution()[0].lower())\")" ; then
   echo "It is not CentOS distribution, ignoring CentOS setup"
   exit 0
fi
Can Tecim
источник
0

Использование этой команды работает в CentOS, Ubuntu и Debian: grep "^NAME=" /etc/os-release |cut -d "=" -f 2 | sed -e 's/^"//' -e 's/"$//'

В Debian это даёт Debian GNU/Linux, в Ubuntu даёт, Ubuntuа в CentOS даёт CentOS Linux.

Преимущество использования grep, cut и sed вместо gawk очевидно: Debian не имеет gawk, установленного по умолчанию, поэтому вы не можете полагаться на него в произвольной коробке Debian.

Вилле Лайтила
источник