Muszę sprawdzić, czy numer wersji Bash to> = do określonego numeru. Na przykład mam:
$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Aby użyć tablic asocjacyjnych, numer wersji bash musi wynosić> = 4.
W moim skrypcie bash chciałbym przetestować jedną linijkę w możliwie najbardziej elegancki / wydajny / czytelny sposób, ale inne podejścia są również akceptowane.
command-line
bash
scripts
versions
WinEunuuchs2Unix
źródło
źródło
$BASH_VERSION
i$BASH_VERSINFO
?--version
Pierwotną intencją była ogólna procedura sprawdzania wszystkich programów poprzez dołączanie i testowanie danych wyjściowych. Odpowiednio zredagowałem pytanie.Odpowiedzi:
Próbować:
BASH_VERSINFO
jest zmienną tablicową tylko do odczytu, której członkowie przechowują informacje o wersji dla tego wystąpienia bash. Od czasu wprowadzenia bash 2.0 jest prawdopodobnie obsługiwany przez wszystkie napotkane wersje bash. Jednak, aby zachować ostrożność, dołączamy wartość domyślną0
dla każdego bash wcześniejszej wersji, dla którego ta zmienna nie jest ustawiona.Wydobywanie informacji o wersji z innych programów
Pytałeś o LibreOffice, Python, jądro itp.
LibreOffice tworzy informacje o wersji, które wyglądają następująco:
Aby wyodrębnić numer wersji:
W przypadku python:
Aby uzyskać wersję jądra, użyj
uname
:źródło
uname -r
„4.9.0-2-amd64”, który mógłby przetestować większy niż mój „4.11.1-041101-ogólny” przy regularnym teście bash, gdy w rzeczywistości mój numer wersji jest większy.$ python --version
który zwracaPython 2.7.12
. @ wjandrea-- dzięki za link +1. Być może mógłbym zbudować tabelę wszystkich nazw programów i minimalnych numerów wersji. Następnie przekaż tabelę do zmodyfikowanej kopiipython
podanego linku. Ponieważ można wywoływać tylko skompilowany Python, możnagrub
by pomyśleć, że istnieje plik binarny, aby to zrobić lub jest to możliwe w powłoce.Zamiast porównywać numery wersji, możesz bezpośrednio przetestować samą funkcję.
declare -A
zwraca2
(przynajmniej w Bash 3.2), jeśli nie rozpoznaje-A
, więc przetestuj to (wyświetla również błąd):(
declare -A var
kończy się również niepowodzeniem, jeślivar
jest tablicą niepowiązaną, więcunset
najpierw).Chociaż tak naprawdę nie zakładam, że ktoś będzie chciał korzystać z funkcji backportu w Bash, ogólnie bardziej odpowiednie jest sprawdzanie funkcji, a nie wersji. Nawet w przypadku Basha ktoś może skompilować wersję z ograniczonymi funkcjami ...
Bardziej ogólny przypadek testowania numerów wersji składa się z dwóch części: 1) jak znaleźć poprawny numer wersji do przetestowania oraz 2) jak go porównać z inną wartością.
Pierwszy jest trudniejszy. Wiele programów podaje swój numer wersji za pomocą flagi wiersza polecenia, takiej jak
--version
lub-v
, ale format wyjściowy jest różny, a programowe wybranie numeru wersji może być trudne. Następnie pojawia się problem z zainstalowaniem kilku wersji tego samego programu w tym samym czasie.Drugi zależy od pewnej znajomości formatu numerów wersji.
dpkg
mogę porównać numery wersji w stylu Debiana (które, jak sądzę, zawierają wersje typu semver jako podzbiór):Lub po prostu połączyć powyższe:
źródło
Istnieje kilka sposobów na osiągnięcie tego, co chcesz osiągnąć.
1. Użyj $ BASH_VERSION
Wystarczy zobaczyć, co jest
$BASH_VERSION
zmienne. Osobiście użyłbym podpowłoki tak:Pamiętaj, że
<<<
składnia dla here-doc nie jest przenośna, jeśli zamierzasz jej używać/bin/sh
, czyli Dash na Ubuntu i może być czymś innym w innym systemieAlternatywnym sposobem jest użycie instrukcji case lub if. Osobiście zrobiłbym to:
Prawdopodobnie ze względu na przenośność powinieneś prawdopodobnie sprawdzić, czy taka zmienna jest w ogóle ustawiona w ogóle za pomocą czegoś takiego
[ -n $BASH_VERSION ]
Można to całkowicie przepisać jako funkcję do użycia w skrypcie. Coś długiego w linii:
To nie jest jedna linijka, chociaż jest to znacznie lepsze. Jakość ponad ilość.
2. Sprawdź, co jest zainstalowane
W tym celu należy filtrować dane wyjściowe
apt-cache policy
podobnedpkg-query
może się również przydać przy filtrowaniu przezawk
.Zauważ, że nie jest to przenośne, ponieważ jeśli nie ma go
dpkg
lub nie jestapt
zainstalowane w systemie (na przykład RHEL lub FreeBSD), nic ci to nie da.3. Użyj set -e, aby wyjść ze skryptu, jeśli wystąpi błąd
Jednym ze sposobów obejścia tego jest po prostu skorzystanie z tablic asocjacyjnych i wyjście, gdy
bash
nie można ich użyć.set -e
wiersz poniżej#!/bin/bash
pozwoli skryptowi zakończyć pracę, jeśli skrypt nie może użyć tablicy asocjacyjnej.Będzie to wymagać od użytkownika wyraźnego powiedzenia: „Hej, naprawdę potrzebujesz wersji bash 4.3 lub nowszej, w przeciwnym razie skrypt nie będzie działał”. Odpowiedzialność spoczywa na użytkowniku, choć niektórzy mogą twierdzić, że nie jest to dobre podejście do tworzenia oprogramowania.
4. Porzuć wszelką nadzieję i napisz przenośne skrypty zgodne z POSIX
bash
skrypty nie są przenośne, ponieważ ich składnia nie jest kompatybilna z powłoką Bourne'a. Jeśli skrypt, który piszesz, będzie używany w wielu różnych systemach, nie tylko w Ubuntu, porzuć wszelką nadzieję i znajdź sposoby na użycie czegoś innego niż tablice asocjacyjne. Może to obejmować dwie tablice lub parsowanie pliku konfiguracyjnego. Zastanów się także nad przejściem na inny język, Perl lub Python, gdzie składnia jest co najmniej bardziej przenośna niżbash
.źródło
yad --version
zwraca,0.37.0 (GTK+ 3.18.9)
ale obecnie dostępne są nowe funkcje0.39
.Jednowarstwowy nie jest możliwy, ale możliwy jest skrypt bash
Opracowałem skrypt oparty na odpowiedziach w przepełnieniu stosu. Jedna z tych odpowiedzi doprowadziła do napisania przez pracownika Dell porównania numerów wersji w 2004 r. Dla aplikacji DKMS.
Kod
Poniższy skrypt bash musi zostać oznaczony jako wykonywalny za pomocą polecenia
chmod a+x script-name
. Używam nazwy/usr/local/bin/testver
:źródło