Как получить имя распространения и номер версии в простом сценарии оболочки?

Я работаю над простым сценарием bash, который должен работать в дистрибутивах Ubuntu и CentOS (поддержка Debian и Fedora / RHEL будет плюсом), и мне нужно знать имя и версию дистрибутива, в котором работает скрипт ( чтобы инициировать определенные действия, например создание репозиториев). Пока что у меня есть это:

OS=$(awk '/DISTRIB_ID=/' /etc/*-release | sed 's/DISTRIB_ID=//' | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/') VERSION=$(awk '/DISTRIB_RELEASE=/' /etc/*-release | sed 's/DISTRIB_RELEASE=//' | sed 's/[.]0/./') if [ -z "$OS" ]; then OS=$(awk '{print $1}' /etc/*-release | tr '[:upper:]' '[:lower:]') fi if [ -z "$VERSION" ]; then VERSION=$(awk '{print $3}' /etc/*-release) fi echo $OS echo $ARCH echo $VERSION 

Это похоже на работу, возвращая ubuntu или centos (я еще не пробовал других) в качестве названия выпуска. Однако у меня есть ощущение, что должен быть более простой и надежный способ узнать это – это правда?

  • Определить текущее имя оболочки
  • Как определить, экспортированы ли переменные оболочки или нет?
  • Файл "mv" с искаженным именем по номеру inode?
  • Замена места для команды paste
  • Разные выходы команд «ls. *» И «ls *.»
  • для цикла для итерации через некоторую файловую n-ю позицию
  • Это не работает для RedHat. / etc / redhat-release содержит: Redhat Linux Entreprise release 5.5

    Итак, версия не является третьим словом, вам лучше использовать:

     OS_MAJOR_VERSION=`sed -rn 's/.*([0-9])\.[0-9].*/\1/p' /etc/redhat-release` OS_MINOR_VERSION=`sed -rn 's/.*[0-9].([0-9]).*/\1/p' /etc/redhat-release` echo "RedHat/CentOS $OS_MAJOR_VERSION.$OS_MINOR_VERSION" 

  • Операторы перенаправления всегда открывают дескрипторы файлов параллельно?
  • получить приглашение оболочки в python
  • ошибка во время цикла с sed
  • Извлечение каталога из stdout из wget
  • Как использовать команду вставки для многих файлов, имена которых не являются цифрами? (вставьте столбцы из каждого файла в один файл)
  • Zsh - более интеллектуальная автокоррекция
  • 17 Solutions collect form web for “Как получить имя распространения и номер версии в простом сценарии оболочки?”

    Чтобы получить OS и VER , последним стандартом является /etc/os-release . До этого была lsb_release и /etc/lsb-release . До этого вам приходилось искать разные файлы для каждого дистрибутива.

    Вот что я предлагаю

     if [ -f /etc/os-release ]; then # freedesktop.org and systemd . /etc/os-release OS=$NAME VER=$VERSION_ID elif type lsb_release >/dev/null 2>&1; then # linuxbase.org OS=$(lsb_release -si) VER=$(lsb_release -sr) elif [ -f /etc/lsb-release ]; then # For some versions of Debian/Ubuntu without lsb_release command . /etc/lsb-release OS=$DISTRIB_ID VER=$DISTRIB_RELEASE elif [ -f /etc/debian_version ]; then # Older Debian/Ubuntu/etc. OS=Debian VER=$(cat /etc/debian_version) elif [ -f /etc/SuSe-release ]; then # Older SuSE/etc. ... elif [ -f /etc/redhat-release ]; then # Older Red Hat, CentOS, etc. ... else # Fall back to uname, eg "Linux <version>", also works for BSD, etc. OS=$(uname -s) VER=$(uname -r) fi и if [ -f /etc/os-release ]; then # freedesktop.org and systemd . /etc/os-release OS=$NAME VER=$VERSION_ID elif type lsb_release >/dev/null 2>&1; then # linuxbase.org OS=$(lsb_release -si) VER=$(lsb_release -sr) elif [ -f /etc/lsb-release ]; then # For some versions of Debian/Ubuntu without lsb_release command . /etc/lsb-release OS=$DISTRIB_ID VER=$DISTRIB_RELEASE elif [ -f /etc/debian_version ]; then # Older Debian/Ubuntu/etc. OS=Debian VER=$(cat /etc/debian_version) elif [ -f /etc/SuSe-release ]; then # Older SuSE/etc. ... elif [ -f /etc/redhat-release ]; then # Older Red Hat, CentOS, etc. ... else # Fall back to uname, eg "Linux <version>", also works for BSD, etc. OS=$(uname -s) VER=$(uname -r) fi и if [ -f /etc/os-release ]; then # freedesktop.org and systemd . /etc/os-release OS=$NAME VER=$VERSION_ID elif type lsb_release >/dev/null 2>&1; then # linuxbase.org OS=$(lsb_release -si) VER=$(lsb_release -sr) elif [ -f /etc/lsb-release ]; then # For some versions of Debian/Ubuntu without lsb_release command . /etc/lsb-release OS=$DISTRIB_ID VER=$DISTRIB_RELEASE elif [ -f /etc/debian_version ]; then # Older Debian/Ubuntu/etc. OS=Debian VER=$(cat /etc/debian_version) elif [ -f /etc/SuSe-release ]; then # Older SuSE/etc. ... elif [ -f /etc/redhat-release ]; then # Older Red Hat, CentOS, etc. ... else # Fall back to uname, eg "Linux <version>", also works for BSD, etc. OS=$(uname -s) VER=$(uname -r) fi 

    Я думаю, что uname чтобы получить ARCH по-прежнему является лучшим способом. Но пример, который вы дали, очевидно, обрабатывает только системы Intel. Я бы назвал это BITS следующим образом:

     case $(uname -m) in x86_64) BITS=64 ;; i*86) BITS=32 ;; *) BITS=? ;; esac 

    Или измените ARCH на более распространенные, но недвусмысленные версии: x86 и x64 или аналогичные:

     case $(uname -m) in x86_64) ARCH=x64 # or AMD64 or Intel64 or whatever ;; i*86) ARCH=x86 # or IA32 or Intel32 or whatever ;; *) # leave ARCH as-is ;; esac 

    но, конечно, это зависит от вас.

    Я бы пошел с этим в качестве первого шага:

     ls /etc/*release 

    В Gentoo, RedHat, Arch и SuSE есть файл, называемый, например, /etc/gentoo-release . Кажется, это популярно, проверьте этот сайт о файлах-релизах .

    Debian & Ubuntu также должен иметь /etc/lsb-release которая также содержит информацию о выпуске, и будет отображаться с предыдущей командой.

    Еще один быстрый – uname -rv . Если ядро ​​установлено, это ядро ​​дистрибутива, вы обычно иногда находите его там.

    lsb_release -a . Работает на Debian, и я думаю, Ubuntu, но я не уверен в этом. Обычно он должен существовать во всех дистрибутивах GNU / Linux, так как это LSB (стандартная база Linux).

    Однострочный, резервный, один вывод, без ошибок.

     lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om 
    1. lsb- * не установлен / не существует на базе систем CentOS или Debian
    2. / proc / * не существует в OSX

    Возьмите совет от разработчиков javascript. Не проверяйте версию, проверьте ее. Это некрасиво, но это работает. При необходимости развернуть.

     function os_type { case `uname` in Linux ) LINUX=1 which yum && { echo centos; return; } which zypper && { echo opensuse; return; } which apt-get && { echo debian; return; } ;; Darwin ) DARWIN=1 ;; * ) # Handle AmgiaOS, CPM, and modified cable modems here. ;; esac } 

    В порядке наиболее вероятного успеха:

     cat /etc/*version cat /proc/version #linprocfs/version for FreeBSD when "linux" enabled cat /etc/*release uname -rv 

    охватывают большинство случаев (AFAIK): Debian, Ubuntu, Slackware, Suse, Redhat, Gentoo, * BSD и, возможно, другие.

    Для большинства современных систем ОС Linux файл /etc/os-release действительно становится стандартным и входит в большинство ОС. Поэтому внутри вашего сценария Bash вы можете просто включить файл, и у вас будет доступ ко всем описанным здесь переменным (например: NAME, VERSION, …)

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

     if [ -f /etc/os-release ] then . /etc/os-release else echo "ERROR: I need the file /etc/os-release to determine what my distribution is..." # If you want, you can include older or distribution specific files here... exit fi и if [ -f /etc/os-release ] then . /etc/os-release else echo "ERROR: I need the file /etc/os-release to determine what my distribution is..." # If you want, you can include older or distribution specific files here... exit fi 
     python -c "import platform;print(platform.platform())" 

    Если файл /etc/debian_version существует, дистрибутив – Debian или производный Debian. Этот файл может иметь номер выпуска; на моей машине сейчас 6.0.1 . Если он тестируется или нестабилен, он может сказать, что он тестируется / нестабилен, или может иметь номер предстоящей версии. Мое впечатление, что по крайней мере на Ubuntu этот файл всегда тестируется / нестабилен и что они не помещают номер выпуска в него, но кто-то может исправить меня, если я ошибаюсь.

    Fedora (по крайней мере, последние версии) имеет аналогичный файл, а именно: /etc/fedora-release .

    2 пути от многих:

    1) использовать

     lsb_release -a 

    Я тестировал его на CentOS 5.5 и Ubuntu 10.04

    выход для CentOS:

     LSB Version: :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch Distributor ID: CentOS Description: CentOS release 5.5 (Final) Release: 5.5 Codename: Final 

    и для Ubuntu:

     LSB Version: :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch Distributor ID: CentOS Description: CentOS release 5.5 (Final) Release: 5.5 Codename: Final 

    2) введите следующую команду:

     cat /etc/*-release 

    Я тестировал его на CentOS 5.5 и Ubuntu 10.04, и он отлично работает.

    Если вы не можете или не хотите использовать файл выпуска LSB (из-за зависимостей, которые вносит пакет), вы можете посмотреть файлы релиза, зависящие от дистрибутива. У Bcfg2 есть зонд для дистрибутива, который вы могли бы использовать: http://trac.mcs.anl.gov/projects/bcfg2/browser/doc/server/plugins/probes/group.txt

    Этот скрипт работает на Debian (может потребоваться некоторая настройка на Ubuntu)

     #!/usr/bin/env bash echo "Finding Debian/ Ubuntu Codename..." CODENAME=`cat /etc/*-release | grep "VERSION="` CODENAME=${CODENAME##*\(} CODENAME=${CODENAME%%\)*} echo "$CODENAME" # => saucy, precise, lucid, wheezy, squeeze 

    Вот моя простая версия chech_distro. ^^;

     #!/usr/bin/env bash check_distro2(){ if [[ -e /etc/redhat-release ]] then DISTRO=$(cat /etc/redhat-release) elif [[ -e /usr/bin/lsb_release ]] then DISTRO=$(lsb_release -d | awk -F ':' '{print $2}') elif [[ -e /etc/issue ]] then DISTRO=$(cat /etc/issue) else DISTRO=$(cat /proc/version) fi } check_distro2 echo $DISTRO 

    Без версии, всего лишь dist:

     cat /etc/issue | head -n +1 | awk '{print $1}' 

    Это было протестировано на Ubuntu 14 и CentOS 7

     cat /etc/os-release | grep "PRETTY_NAME" | sed 's/PRETTY_NAME=//g' | sed 's/["]//g' | awk '{print $1}' 

    Я нахожу хороший сценарий отсюда, который работает для большинства обычных Linux-прогонов:

     #! /bin/bash # return an awkable string consisting of # unix OS type, or # Linux dist, or # a long guess (based on /proc), or # no clue giveUp () { echo "Unknown" exit 0 } # keep this easily awkable, prepending an initial clue versionGuess () { if [ -e /proc/version ]; then echo -n "Unsure " cat /proc/version exit 0 fi return 1 } # if we have ignition, print and exit gotDist () { [ -n "$1" ] && echo "$1" && exit 0 } # we are only interested in a single word "dist" here # various malformations can occur; admin will have to code appropately based on output linuxRelease () { if [ -r /etc/lsb-release ]; then dist=$(grep 'DISTRIB_ID' /etc/lsb-release | sed 's/DISTRIB_ID=//' | head -1) gotDist "$dist" fi dist=$(find /etc/ -maxdepth 1 -name '*release' 2> /dev/null | sed 's/\/etc\///' | sed 's/-release//' | head -1) gotDist "$dist" dist=$(find /etc/ -maxdepth 1 -name '*version' 2> /dev/null | sed 's/\/etc\///' | sed 's/-version//' | head -1) gotDist "$dist" return 1 } # start with uname and branch the decision from there dist=$(uname -s 2> /dev/null) if [ "$dist" = "Linux" ]; then linuxRelease versionGuess giveUp elif [ -n "$dist" ]; then echo "$dist" exit 0 else versionGuess giveUp fi # we shouldn't get here giveUp # done 

    Эта команда работает для дистрибутивов на основе Debian и Redhat: используя tr фильтр, вы конвертируете документ в формат с одним словом на строку и затем подсчитываете первую строку, содержащую имя распространения.

     tr -s ' \011' '\012' < /etc/issue | head -n 1 
    Linux и Unix - лучшая ОС в мире.