Het volgende is wat ik momenteel gebruik om de versie van Debian te testen. In plaats van het te doen op deze manier, kan ik het beknopter maken?
#!/bin/bash VERSION=NONE if [ $(cat /etc/debian_version) == "7.3" ]; then VERSION=7 elif [ $(cat /etc/debian_version) == "7.2" ]; then VERSION=7 elif [ $(cat /etc/debian_version) == "7.1" ]; then VERSION=7 elif [ $(cat /etc/debian_version) == "7.0" ]; then VERSION=7 fi
Ik weet dat dit niet de meest aantrekkelijke manier is om dit te doen. Wat ik wil, is begrijpen hoe ik het bestand op /etc/debian_version
moet gebruiken om het versienummer voor .
te lezen en het nummer erna te negeren.
Ik heb geprobeerd
if [ $(cat /etc/debian_version) == "7.*" ]; then
en ik heb het ook geprobeerd
if [ $(cat /etc/debian_version) == "7.2|7.1|7.0" ]; then
Maar geen van beide werkte voor mij. Ik wil mijn script toekomstbestendig maken, zodat als Debian 7.4 wordt vrijgegeven, ik “niet alle scripts die hiervan afhankelijk zijn opnieuw hoef te bekijken en ze te wijzigen
Ik ben ook op de hoogte van de lsb_release -a
laat me de relatieve informatie zien, ik weet gewoon niet hoe ik daaruit moet “knippen” wat ik wil en controleer of het Debian 6 of 7 is. Het originele script, zoals u zich kunt voorstellen , is behoorlijk lang.
Alle andere berichten waar je me naar kunt verwijzen, zouden ook gewaardeerd worden door de methode te gebruiken om de reactie uit elkaar te halen om alleen het deel uit te snijden dat ik wil.
Antwoord
Er zijn veel manieren om te doen wat je wilt. Deze verwijdert alleen de decimale punt en alles erna uit het versienummer:
VERSION=$(sed "s/\..*//" /etc/debian_version)
\..*
betekent een punt ( \.
) gevolgd door nul of meer van een willekeurig teken (.*
). Dus voor sed
betekent de uitdrukking s/\..*//
de punt en alles wat erop volgt met niets vervangen. Het resultaat van het sed
commando wordt opgeslagen in de omgevingsvariabele VERSION
.
Het bovenstaande elimineert de noodzaak voor de if / then / elif /…/ fi-statements. Het werkt met zowel bash als gewone / bin / sh.
MEER: sed
is een stream-editor: dat betekent dat het regels leest van stdin, ze bewerkt volgens de instructies en ze (meestal) naar stdout stuurt. In dit geval geven we het een “vervangende” instructie. s/foo/bar/
betekent bijvoorbeeld: zoek de eerste instantie van foo en vervang deze door bar. In een speciaal geval betekent s/foo//
foo
vervangen door niets. In ons geval willen we een punt, gevolgd door een willekeurig teken, vervangen door niets. Nu is een punt “.” behalve dat sed
normaal gesproken een punt behandelt als “elk teken”. Dus we moeten eraan “ontsnappen” door er een backslash voor te plaatsen. Wanneer sed
\.
ziet, weet het dat we een letterlijke punt bedoelen. We willen ook alle tekens na de punt wissen. Om “elk teken” weer te geven, gebruiken we een punt .
(geen escape). Om algemeen te zijn, willen we alle tekens na de punt verwijderen, ongeacht hoeveel het er zijn. Dus, terwijl in de taal van sed
“een punt elk teken betekent, betekent de ster” elk nummer van het voorgaande teken “(dat nul kan zijn). Dus punt-ster .*
betekent nul of meer van een willekeurig teken. Dus, alles bij elkaar opgeteld, s/\..*//
vertelt sed
dat als het een punt vindt, mogelijk gevolgd door iets, het dan door niets vervangt.
Commentaar
Antwoord
Hier is een oplossing die bash gebruikt, geen externe hulpprogrammas , en is een enkele aanroep
read -d . VERSION < /etc/debian_version
Dit leest /etc/debian_version
, splitst de invoer op de punt (.
), wijst alles vóór de punt toe aan VERSION
en verwijdert alles erna.
IFS="." read VERSION VERSION_MINOR < /etc/debian_version
Dit is iets anders omdat het alles na de periode opslaat in VERSION_MINOR
IFS="." read -a VERSION < /etc/debian_version
Dit is het krachtigste in dat het splitst zich op de punt en wijst het toe aan de array $VERSION
. Als de versie 1.2.3
is, dan ${VERSION[0]} == 1
${VERSION[1]} == 2
en ${VERSION[2]} == 3
.
Reacties
- Dit is uitstekend!Ik ' heb nog nooit gezien dat lezen op deze manier wordt gebruikt!
Antwoord
case `cat /etc/debian_version` in 7*) VERSION=7;; *) VERSION=NONE;; esac
Dit kan natuurlijk worden uitgebreid om meer versies te herkennen.
s/
gedeelte betekent, maar hoe zit het met\..*
?\.
Ik kon ' de tweede . Bedankt voor het verduidelijken van dit voor mij.