Vraag Hoe maak je een UUID aan in bash?


In Java is het mogelijk om een ​​willekeurige te maken UUID:

UUID uuid = UUID.randomUUID();

Hoe dit te doen in Bash?


163
2018-01-16 13:41


oorsprong




antwoorden:


Zie de uuidgen programma dat deel uitmaakt van de e2fsprogs pakket.

Volgens deze, libuuid is nu onderdeel van util-linux en de opname in e2fsprogs wordt afgebouwd. Op nieuwe Ubuntu-systemen echter uuidgen is nu in de uuid-runtime pakket.

Een uuid maken en opslaan in een variabele:

uuid=$(uuidgen)

Op mijn Ubuntu-systeem worden de alfakarakters uitgevoerd als kleine letters en op mijn OS X-systeem worden ze uitgevoerd als hoofdletters (met dank aan David voor het wijzen in een opmerking).

Omschakelen naar hoofdletters (na het genereren zoals hierboven):

uuid=${uuid^^}

Om over te schakelen naar alle kleine letters:

uuid=${uuid,,}

Als u bijvoorbeeld twee UUID's hebt en deze in Bash wilt vergelijken, negeert u hun case, kunt u een tolower() stijl vergelijking als deze:

if [[ ${uuid1,,} == ${uuid2,,} ]]

185
2018-01-16 14:01



hey, nee eerlijk! mijn e2fsprogs kwam daar niet mee! ik wil er een, waar haal ik die vandaan? (update: ahhh ... debian steekt het in de uuid-runtime pakket zonder duidelijke reden ... +1 voor jou) - quack quixote
uuidgen komt ingebouwd op freeBSD. het zit niet altijd in het e2fsprogs-pakket. - Good Person
@Rob: om je oorspronkelijke vraag te beantwoorden, is het voor drive labels. - Dennis Williamson
Ik merk dat uuidgen op Mac in hoofdletters in Ubuntu (uuidgen van util-linux 2.20.1) in kleine letters uitzendt. Waarom het verschil? Ook Ubuntu vermeldde waar de tool vandaan kwam maar op Mac, er is geen versie-informatie en ook niet van welk pakket het afkomstig is. - David
@David: Ik geloof dat het deel uitmaakt van het basisbesturingssysteem op OS X. Ik heb geen idee waarom de ene hoofdletter is en de andere lager. Het maakt niet echt uit, aangezien het ofwel geldige hexadecimale tekens vertegenwoordigt (echo -e 'f\nF' | grep '[[:xdigit:]]' geeft beide lijnen weer). Als het voor jou van belang is en je hebt Bash 4, dan kun je dit doen om het kleine letters te maken: uuid=$(uuidgen); uuid=${uuid,,} of dit om het hoofdlettergebruik te maken: uuid=$(uuidgen); uuid=${uuid^^} of iets in deze zin om een ​​a te doen tolower() stijltest: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


Om variatie toe te voegen zonder externe afhankelijkheden toe te voegen, aan Linux je kunt doen:

UUID=$(cat /proc/sys/kernel/random/uuid)

Om slechte praktijken te verspreiden, op FreeBSD, onder de linux-compatibiliteitslaag (linuxulator?),

UUID=$(cat /compat/linux/proc/sys/kernel/random/uuid)

Referenties:


128
2017-08-07 12:55



Dit is geweldig. - Tom O'Connor
Dit moet worden vermeden omdat het hoogst niet-draagbaar is (hoewel FreeBSD supplies / compat / linux / proc / sys / kernel / random / uuid voor slecht geschreven applicaties levert) - Good Person
Het past perfect voor gebruik binnen de initrd-afbeelding - Maximilian
De FreeBSD-methode lijkt niet op Mac OS X (noch de Linux-methode). Tenminste lijkt uuidgen vooraf te zijn geïnstalleerd op de Mac (of is geïnstalleerd met iets anders dat ik heb geïnstalleerd). - David
Dit is een beter antwoord voor echt minimale opstellingen, zoals een Docker-container. - jacderida


Voor de volledigheid ... Er is ook een UUID-generator geïnstalleerd met de dbus pakket op Debian. Ik miste het om eerder rond te kijken. Het is waarschijnlijk hetzelfde algoritme als het e2fsprogs-pakket, maar het voegt geen streepjes toe, dus het kan een beetje schoner voor u zijn:

$ uuidgen
387ee6b9-520d-4c51-a9e4-6eb2ef15887d

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity voegt een veiligheidstip toe: "DBus UUID's zijn niet gerelateerd aan of compatibel met RFC 4122. Trouwens, dbus-uuidgen gebruikt altijd het Unix-tijdstempel als laatste 4 bytes. Dus ze kunnen ongeschikt zijn voor sommige toepassingen. "(Bedankt, Grawity, ik had dat moeten zien in de manpage.)


28
2018-01-16 14:18



DBus UUID's zijn niet gerelateerd aan of compatibel met RFC 4122. Bovendien, dbus-uuidgengebruikt altijd het Unix-tijdstempel als laatste 4 bytes. Dus ze kunnen ongeschikt zijn voor sommige toepassingen. - grawity
Hetzelfde werkt ook op Fedora-25 ... - kmonsoor


Als je niet afhankelijk wilt zijn van andere uitvoerbare bestanden, of als je ze niet kunt gebruiken, is hier de pure bash-versie van hier:

# Generate a pseudo UUID
uuid()
{
    local N B T

    for (( N=0; N < 16; ++N ))
    do
        B=$(( $RANDOM%255 ))

        if (( N == 6 ))
        then
            printf '4%x' $(( B%15 ))
        elif (( N == 8 ))
        then
            local C='89ab'
            printf '%c%x' ${C:$(( $RANDOM%${#C} )):1} $(( B%15 ))
        else
            printf '%02x' $B
        fi

        for T in 3 5 7 9
        do
            if (( T == N ))
            then
                printf '-'
                break
            fi
        done
    done

    echo
}

[ "$0" == "$BASH_SOURCE" ] && uuid

15
2018-05-21 21:12



De T variabele kan worden geëlimineerd en de for T loop kan worden gewijzigd in: case $N in 3 | 5 | 7 | 9) printf '-';; esac (uitgesplitst op afzonderlijke regels indien gewenst). - Dennis Williamson
Ik heb een opmerking toegevoegd aan de code op de github-link die een versie toont die gebruikt case om het te elimineren if uitspraken evenals de innerlijke for uitspraak. Het maakt de code veel netter. Merk op dat beide B%15 zou moeten zijn B%16 en B%255 zou moeten zijn B%256. - Dennis Williamson


Ik vond dit script "one-liner" nuttig als uuidgen niet beschikbaar is. Dit omzeilt ook elke noodzaak om externe modules voor Perl of Python te installeren.

od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'

Getest op SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 en nieuwer met succes. Ik ben benieuwd of dit vatbaar is voor niet-uniekheid, maar ik ben de afgelopen tien jaar niet 'gebeten'. Natuurlijk, head -1 kan worden vervangen door head -_other-value_ | tail -1 te.

Uitleggen,

/dev/random en /dev/urandom zijn kernel random generators.

od (octal dump) heeft een hexadecimale uitvoerschakelaar (-x) die 16 bytes per regel produceert.

head -n [| tail -1] (waarbij n> 0) slechts één regel van de vorige uitvoer extraheert.

awk stelt de OutputFieldSeparator in als een koppelteken, overal waar een komma voorkomt in de afdrukinstructie. Door velden 2-9 onafhankelijk op te geven, besturen we de koppeltekens en ontdoen we de index / offsetteller die met 'od' voor elke regel met voorvoegsels.

Het resultaat is een patroon van 8-4-4-4-12 kleine letters a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

13
2017-08-25 23:57



Briljant! slechts een enkele regel zonder afhankelijkheden, BSD / macOS-compatibel ... geweldig - dinigo
Do NIET gebruik "staart -1". Als je alleen "od -x / dev / urandom" alleen uitvoert, gaat het voor onbepaalde tijd door, produceert continu meer regels willekeurige gegevens. "staart -1" kan gewoon voor altijd zitten wachten op de "laatste" regel. Anders is het een goede oplossing. - UncaAlby
Let op, staart staat alleen in de "uitleg" als een optionele parameter wanneer het aantal lijnen dat wordt uitgevoerd door het hoofd groter is dan één. Daar om ervoor te zorgen dat een enkele regel van 16 bytes wordt ontvangen door awk, en maakt het geen deel uit van de oorspronkelijke opdracht. De pipe to head van od zuivert de uitvoer voor piping naar tail -1 al. In mijn ervaring is de enige keer dat de staart voor altijd wacht met een -f argument. Het spijt me als de uitleg niet duidelijk was waar het aangeeft dat het gebruik van staart -1 alleen nodig is wanneer de uitvoer van het hoofd meer dan één lijn produceert. - dan
Do niet gebruik dit, het is volledig in strijd met de UUID-specificatie. Alleen versie 4 UUID mag willekeurig zijn zoals dit. - jlh
@jlh Ik weet niet zeker waarom deze vraag is afgesloten, maar hier is een vaste versie die deze aanpak compatibel maakt met UUID-v4: od -x /dev/urandom | head -1 | awk '{OFS="-"; srand($6); sub(/./,"4",$5); sub(/./,substr("89ab",rand()*4,1),$6); print $2$3,$4,$5,$6,$7$8$9}' - Stuart P. Bentley


Precies zo voelt Python zich buitengesloten:

python  -c 'import uuid; print uuid.uuid1()'
2d96768e-02b3-11df-bec2-001e68b9d147

Om het in de shell te gebruiken:

myvar=$(python  -c 'import uuid; print uuid.uuid1()')

Zie de Python Documentatie UUID voor de soorten UUIDS die kunnen worden gegenereerd.

Om een ​​system-id-compatibel bestand te genereren op een niet-gesystematiseerde machine, zou je Python kunnen gebruiken om het op deze manier te doen:

python -c 'import re; import uuid; print re.sub("-","",str(uuid.uuid4()))' \
 > /etc/machine-id

12
2018-01-16 15:26





Perl biedt een UUID-bibliotheek op basis van de e2fsprogs pakket. Op mijn Debian-systeem is het de libuuid-perl pakket. Hier is een voorbeeld one-liner; zien man uuid voor meer:

$ perl -e 'use UUID;  UUID::generate($uuid);  UUID::unparse($uuid, $string);  print "my new UUID is $string \n";'
my new UUID is 3079e9ce-41d4-4cf3-9f90-d12f8bb752e4

Dit zou triviaal zijn om toe te voegen aan een shellscript met backticks of $() notatie:

#!/bin/bash
# ...do some stuff
$myvar = $(perl -e 'use UUID;  UUID::generate($uuid);  UUID::unparse($uuid, $string);  print "$string";')
# ...do some more stuff

11
2018-01-16 13:54



+1 - Help me veel! - rafa.ferreira


apt-get install uuid

Werkte voor mij, dan liep id uuid


3
2018-06-19 09:07





Ik schreef een kleine Bash-functie met behulp van Python om een ​​willekeurig aantal UUID's in bulk te genereren:

# uuid [count]
#
# Generate type 4 (random) UUID, or [count] type 4 UUIDs.
function uuid()
{
    local count=1
    if [[ ! -z "$1" ]]; then
        if [[ "$1" =~ [^0-9] ]]; then
            echo "Usage: $FUNCNAME [count]" >&2
            return 1
        fi

        count="$1"
    fi

    python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range('"$count"')]))'
}

Als u de voorkeur geeft aan kleine letters, wijzigt u:

python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range('"$count"')]))'

Naar:

python -c 'import uuid; print("\n".join([str(uuid.uuid4()) for x in range('"$count"')]))'

1
2017-08-03 22:16





Bekijk de OSSP UUID-bibliotheek (http://www.ossp.org/pkg/lib/uuid/) en overweeg het te installeren. Sommige projecten bieden het als een optie (bijvoorbeeld PostgreSQL). Het behandelt correct versie 3 en versie 5 UUID's, dat verder ging dan wat mijn geïnstalleerde bibliotheek (bijvoorbeeld e2fsprogs) aankon. Gelukkig heeft openSUSE het in een van de belangrijkste repo's. Het krijgen van een versie om te werken met Windows (bijvoorbeeld Cygwin) of MySQL is flail geweest. Lijkt erop dat het tijd is om over te schakelen naar Linux / PostgreSQL / Python (en ik hield zo van de SQLyog GUI naar MySQL / MariaDB) omdat ik echt v3- en v5 UUID's nodig heb.


1
2017-09-23 23:37



Helemaal mee eens! Voor mijn use case was het perfect omdat het ook namespacing ondersteunt via de -v3 ns:URL custom-data zaaimechanisme. - Roberto Andrade