Czasami twoje skrypty muszą zachowywać się inaczej w różnych systemach Linux. Jak mogę ustalić, na której wersji systemu Linux działa skrypt?
Czasami twoje skrypty muszą zachowywać się inaczej w różnych systemach Linux. Jak mogę ustalić, na której wersji systemu Linux działa skrypt?
Odpowiedzi:
Nie próbuj przyjmować założeń na podstawie tego, co możesz, a czego nie możesz zrobić, ponieważ w ten sposób leży szaleństwo (zobacz także „Wykrywanie agenta użytkownika”). Zamiast tego sprawdź, czy obsługiwane jest to, co chcesz, i jak to zrobić za pomocą dowolnej komendy lub lokalizacji pliku, której chcesz użyć.
Na przykład, jeśli chcesz zainstalować pakiet, możesz wykryć, czy korzystasz z systemu podobnego do Debiana, czy systemu podobnego do RedHat, sprawdzając obecność dpkg lub rpm (najpierw sprawdź dpkg, ponieważ maszyny Debiana mogą mieć polecenie rpm na nich ...). Podejmuj decyzję, co robić w oparciu o to, a nie tylko czy jest to system Debian czy RedHat. W ten sposób automatycznie obsłużysz wszelkie dystrybucje pochodnych, w których nie programowałeś jawnie. Aha, a jeśli twój pakiet wymaga określonych zależności, przetestuj je również i daj użytkownikowi znać, czego brakuje.
Innym przykładem jest majstrowanie przy interfejsach sieciowych. Sprawdź, co zrobić, na podstawie tego, czy istnieje plik / etc / network / interfaces, czy katalog / etc / sysconfig / network-scripts i przejdź od tego.
Tak, to więcej pracy, ale jeśli nie chcesz naprawić wszystkich błędów popełnianych przez twórców stron internetowych w ciągu ostatniej dekady lub więcej, zrobisz to inteligentnie od samego początku.
Nie ma sposobu dystrybucji krzyżowej. Jednak:
- Redhat i przyjaciele: Testuj
/etc/redhat-release
, sprawdzaj zawartość- Debian: Testuj
/etc/debian_version
, sprawdź zawartość- Mandriva i przyjaciele: Testuj
/etc/version
, sprawdzaj zawartość- Slackware: Testuj
/etc/slackware-version
, sprawdź zawartość
Itd. Ogólnie rzecz biorąc, sprawdź /etc/*-release
i /etc/*-version
.
Edycja: Znalazłem mój stary (ponad 1-letni) skrypt bash leżący wokół, który musiałem ułożyć razem przez lata (ma imponujący dziennik CVS sprzed 6 lat). Może już nie działać poprawnie w obecnej postaci i mogę nie będzie Ci przeszkadzać, aby znaleźć zainstalowane dystrybucje do przetestowania, ale powinno to zapewnić dobry punkt wyjścia. Działa dobrze na CentOS, Fedorze i Gentoo. gyaresu przetestował go z powodzeniem na Debianie Lennym.
#!/bin/bash
get_distribution_type()
{
local dtype
# Assume unknown
dtype="unknown"
# First test against Fedora / RHEL / CentOS / generic Redhat derivative
if [ -r /etc/rc.d/init.d/functions ]; then
source /etc/rc.d/init.d/functions
[ zz`type -t passed 2>/dev/null` == "zzfunction" ] && dtype="redhat"
# Then test against SUSE (must be after Redhat,
# I've seen rc.status on Ubuntu I think? TODO: Recheck that)
elif [ -r /etc/rc.status ]; then
source /etc/rc.status
[ zz`type -t rc_reset 2>/dev/null` == "zzfunction" ] && dtype="suse"
# Then test against Debian, Ubuntu and friends
elif [ -r /lib/lsb/init-functions ]; then
source /lib/lsb/init-functions
[ zz`type -t log_begin_msg 2>/dev/null` == "zzfunction" ] && dtype="debian"
# Then test against Gentoo
elif [ -r /etc/init.d/functions.sh ]; then
source /etc/init.d/functions.sh
[ zz`type -t ebegin 2>/dev/null` == "zzfunction" ] && dtype="gentoo"
# For Slackware we currently just test if /etc/slackware-version exists
# and isn't empty (TODO: Find a better way :)
elif [ -s /etc/slackware-version ]; then
dtype="slackware"
fi
echo $dtype
}
Zauważ, że prawdopodobnie będzie to działać poprawnie tylko w Bash. Możesz przepisać go dla innych powłok.
Biorąc to pod uwagę, możesz chcieć przetestować funkcje, a nie dystrybucje. Nie używam tego już po prostu dlatego, że stało się to obciążeniem konserwacyjnym. Łatwiej jest polegać na narzędziach i rozwiązaniach do dystrybucji krzyżowej.
Pod względem koncepcyjnym polega on na:
- Pobierz znany typ pliku „typowa funkcja skryptu inicjującego”. Są one specyficzne dla dystrybucji. Jeśli nie istnieje, przejdź do następnej kontroli dystrybucji.
- Sprawdź istnienie określonej, znanej, często używanej i mało prawdopodobnej zmiany nazwy funkcji z tego podstawowego skryptu. Robimy to za pomocą
type
wbudowanego Bash.type -t
zwraca,function
jeśli ten symbol jest funkcją. Przechodzimyzz
do wyjścia,type -t 2>/dev/null
ponieważ jeśli nazwa nie zostanie zdefiniowana, łańcuch wyjściowy byłby pusty i otrzymalibyśmy błąd składniowy dotyczący brakującej lewej ręki do==
operatora. Jeśli nazwa, którą właśnie sprawdziliśmy, nie jest funkcją, przejdź do następnej kontroli dystrybucji, w przeciwnym razie znaleźliśmy typ dystrybucji.- Na koniec powtórz typ dystrybucji, aby wynik funkcji mógł być łatwo wykorzystany w bloku case .. esac.
Edytuj na wypadek, gdybyś próbował uruchomić to jako prosty skrypt: ten skrypt powinien być pozyskiwany lub dołączany z innych skryptów. Nie wyprowadza niczego samodzielnie, jeśli uruchomisz go takim, jaki jest. Aby to przetestować, zrób to, a następnie wywołaj funkcję, np .:
source /path/to/this/script.sh
get_distribution_type
po znaku zachęty.
Edycja: Należy pamiętać, że ten skrypt nie wymaga uprawnień roota. Nalegam, abyś nie uruchamiał go jako root. Nic nie powinno zaszkodzić, ale nie ma takiej potrzeby.
Znaleziono link do odpowiedniego wpisu na liście mailingowej w dzienniku CVS. Powinien być przydatny w rozpakowywaniu spaghetti ze skryptem inicjującym.
Możesz znaleźć wersję jądra, uruchamiając uname -a
, znalezienie wersji dystrybucji zależy od dystrybucji.
W systemie Ubuntu i niektórych innych systemach operacyjnych można uruchomić lsb_release -a
lub odczytać plik / etc / lsb_release
Debian przechowuje wersję w / etc / debian_version
Większość dystrybucji ma unikalną metodę określania konkretnego rozkładu.
Na przykład:
Redhat (And derivatives): /etc/redhat-release
SUSE: /etc/SUSE-release
Istnieje standard znany jako Linux Standard Base lub LSB . Określa, że powinien istnieć plik o nazwie / etc / lsb-release lub program o nazwie lsb_release, który wyśle echo informacji o dystrybucji Linuksa.
lsb_release -a
lsb_release
nie istnieje w CentOS 6.
python -c 'import platform ; print platform.dist()[0]'
python -c 'import platform; print(platform.dist()[0])'
, ponieważ w ten sposób działa również, jeśli normalnym pythonem jest domyślnie Python3.
Oprócz innych odpowiedzi: Jeśli chcesz tylko parsować jeden plik, większość dystrybucji spersonalizuje login tty przez / etc / issue np .:
Witamy w SUSE Linux Enterprise Server 10 SP2 (i586) - Kernel \ r (\ l).
I tak, wiem, że nie jest optymalny. :)
Wszystko, co musisz zrobić, to wpisać uname -a
ulubioną powłokę. Spowoduje to wydrukowanie nazwy i wersji jądra.
Zgadzam się z Markiem, Adamem i Mihai (nie mogę głosować z powodu niewystarczającej reputacji). Rozwiązania oparte na LSB i jego względnym FHS będą działać z większością dystrybucji i prawdopodobnie będą nadal działać w przyszłości. LSB i FHS są twoimi przyjaciółmi.
Wersja Linuksa jest trudnym pytaniem. Jeśli spojrzymy na to wąsko, mamy wersję jądra, którą można uzyskać za pomocą „ uname -r
”. Wersja dystrybucji jest w większości nieistotna. Niektóre dystrybucje są lepsze (dystrybucje dla przedsiębiorstw, takie jak Redhat Enterprise Linux). Inne dystrybucje, takie jak Gentoo, są w zasadzie ruchomymi celami, które nie mają żadnej sensownej wersji. Jeśli potrzebujesz robić rzeczy w zależności od wersji, spójrz na główne komponenty, które są dla Ciebie odpowiednie:
Component Version command
glibc /lib/libc.so.6
gcc gcc --version
X xdpyinfo
libX11 pkg-config --modversion x11
gtk+ pkg-config --modversion gtk+-2.0
qt-4 pkg-config --modversion QtCore
etc...
Możesz także sprawdzić menu Grub, zwykle daje ci sporo informacji o dystrybucji / wersji :-)
FusionInventory to wieloplatformowe lekkie narzędzie do inwentaryzacji, które może uzyskiwać te informacje na wielu dystrybucjach Linuksa, ale także na BSD, Windows, MacOS X i innych unikach.
Jeśli są dostępne, używają lsb_release
(jak wspomniano kilka razy powyżej), ale jeśli nie, mają bardzo przydatną listę plików i wyrażeń regularnych, aby sprawdzić nazwę i wersję dystrybucji: https://github.com/fusinv/fusioninventory-agent/ blob / 2.2.x / lib / FusionInventory / Agent / Task / Inventory / Input / Linux / Distro / NonLSB.pm # L16 .
Polecam skorzystanie z samego FusionInventory, aby uzyskać te informacje, zamiast ponownego wdrażania własnych skryptów za pomocą tej logiki, ponieważ ich społeczność będzie utrzymywać tę funkcjonalność na bieżąco. Możesz użyć agenta jako takiego (generuje on plik XML / JSON, który jest łatwy do analizy) lub połączyć go z szerszym rozwiązaniem do zarządzania komputerami w sieci, takimi jak GLPI lub Rudder , w zależności od potrzeb.