Frage Wie erstelle ich eine UUID in bash?


In Java ist es möglich, ein zufälliges Objekt zu erstellen UUID:

UUID uuid = UUID.randomUUID();

Wie geht das in Bash?


163
2018-01-16 13:41


Ursprung




Antworten:


Siehe die uuidgen Programm, das Teil der e2fsprogs Paket.

Gemäß diese, libuuid ist jetzt Teil von util-linux und die Aufnahme in e2fsprogs wird auslaufen. Auf neuen Ubuntu-Systemen uuidgen ist jetzt in der uuid-runtime Paket.

So erstellen Sie eine UUID und speichern sie in einer Variablen:

uuid=$(uuidgen)

Auf meinem Ubuntu-System werden die Alpha-Zeichen in Kleinbuchstaben ausgegeben und auf meinem OS X-System werden sie als Großbuchstaben ausgegeben (danke an David, dass er dies in einem Kommentar erwähnt hat).

Um auf alle Großbuchstaben umzuschalten (nach dem Erzeugen wie oben):

uuid=${uuid^^}

Um zu allen Kleinbuchstaben zu wechseln:

uuid=${uuid,,}

Wenn Sie beispielsweise zwei UUIDs haben und diese in Bash vergleichen möchten, ignorieren Sie deren Fall tolower() Stil Vergleich wie folgt:

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

185
2018-01-16 14:01



Hey, nicht fair! Meine e2fsprogs sind damit nicht gekommen! Ich will eins, wo bekomme ich es? (update: ahhh ... debian steckt es in die uuid-runtime Paket ohne ersichtlichen Grund ... +1 für Sie) - quack quixote
Uuidgen kommt auf FreeBSD. Es ist nicht immer im Paket e2fsprogs. - Good Person
@Rob: Um deine ursprüngliche Frage zu beantworten, ist es für Etiketten fahren. - Dennis Williamson
Ich merke, dass Uuidgen auf Mac in Großbuchstaben auf Ubuntu (uuidgen von util-linux 2.20.1) in Kleinbuchstaben ausstrahlt. Warum der Unterschied? Ubuntu hat auch aufgelistet, woher das Tool kam, aber auf dem Mac gibt es keine Versionsinformationen und auch nicht, aus welchem ​​Paket es stammt. - David
@David: Ich glaube, dass es Teil des Basisbetriebssystems unter OS X ist. Ich habe keine Ahnung, warum der eine Großbuchstabe ist und der andere niedriger. Es spielt keine Rolle, da beide gültige Hex-Zeichen darstellen (echo -e 'f\nF' | grep '[[:xdigit:]]' gibt beide Zeilen aus). Wenn es für Sie wichtig ist und Sie Bash 4 haben, können Sie dies tun, um es in Kleinbuchstaben zu schreiben: uuid=$(uuidgen); uuid=${uuid,,} oder dies um es groß zu machen: uuid=$(uuidgen); uuid=${uuid^^} oder etwas in dieser Richtung zu tun tolower() Stiltest: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


Um Vielfalt hinzuzufügen, ohne externe Abhängigkeiten hinzuzufügen, auf Linux du kannst tun:

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

Um schlechte Praktiken zu verbreiten, auf FreeBSD, unter der Linux-Kompatibilitätsschicht (linuxulator?),

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

Verweise:


128
2017-08-07 12:55



Das ist fantastisch. - Tom O'Connor
Dies sollte vermieden werden, da es in hohem Maße nicht portierbar ist (obwohl FreeBSD / compat / linux / proc / sys / kernel / random / uuid für schlecht geschriebene Anwendungen liefert) - Good Person
Es passt perfekt zur Verwendung innerhalb von initrd image - Maximilian
Die FreeBSD-Methode scheint nicht auf Mac OS X (oder der Linux-Methode) zu sein. Zumindest Uuidgen scheint auf dem Mac vorinstalliert zu sein (oder wurde mit etwas anderem installiert, das ich installiert habe). - David
Dies ist eine bessere Antwort für wirklich minimale Setups, wie ein Docker-Container. - jacderida


Nur der Vollständigkeit halber ... Es ist auch ein UUID-Generator installiert mit dem dbus Paket auf Debian. Ich habe es vermisst, mich früher umzusehen. Es ist wahrscheinlich der gleiche Algorithmus wie das e2fsprogs-Paket, aber es fügt keine Bindestriche hinzu, daher könnte es für Sie ein wenig sauberer sein:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity fügt einen Sicherheitshinweis hinzu: "DBus UUIDs sind nicht verwandt mit oder kompatibel mit RFC 4122. Außerdem, dbus-uuidgen verwendet immer den Unix-Zeitstempel als die letzten 4 Bytes. Daher könnten sie für einige Anwendungen ungeeignet sein. "(Danke, Grawity, das hätte ich in der Manpage sehen sollen.)


28
2018-01-16 14:18



DBus-UUIDs sind nicht mit RFC 4122 verwandt oder damit kompatibel. dbus-uuidgen verwendet immer den Unix-Zeitstempel als die letzten 4 Bytes. Sie könnten daher für einige Anwendungen ungeeignet sein. - grawity
Das Gleiche funktioniert auch auf Fedora-25 ... - kmonsoor


Wenn Sie nicht auf andere ausführbare Dateien angewiesen sind oder diese nicht verwenden können, hier ist die reine Bash-Version von 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



Das T Variable kann eliminiert werden und die for T Schleife kann geändert werden zu: case $N in 3 | 5 | 7 | 9) printf '-';; esac (wenn gewünscht, in getrennten Zeilen ausgebrochen). - Dennis Williamson
Ich habe dem Code auf dem GitHub-Link einen Kommentar hinzugefügt, der eine Version mit verwendet case das beseitigen if Aussagen sowie das Innere for Aussage. Es macht den Code viel sauberer. Beachten Sie, dass beide B%15 sollte sein B%16 und B%255 sollte sein B%256. - Dennis Williamson


Ich habe dieses Skript "One-Liner" nützlich gefunden, wo Uuidgen nicht verfügbar ist. Dies schließt auch die Notwendigkeit aus, externe Module für Perl oder Python zu installieren.

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

Getestet auf SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 und neuer erfolgreich. Ich bin neugierig, ob dies zu Nicht-Einzigartigkeit neigt, aber ich bin in den letzten 10 Jahren nicht 'gebissen' worden. Na sicher, head -1 könnte mit ersetzt werden head -_other-value_ | tail -1 auch.

Erklären,

/dev/random und /dev/urandom sind Kernel-Zufallsgeneratoren.

od (Octal Dump) hat einen Hex-Ausgabeschalter (-x), der 16 Bytes pro Zeile erzeugt.

head -n [| tail -1] (wobei n> 0 ist) extrahiert nur eine Zeile der vorherigen Ausgabe.

awk Legt fest, dass der OutputFieldSeparator überall dort, wo in der print-Anweisung ein Komma auftritt, ein Bindestrich ist. Durch unabhängiges Festlegen der Felder 2-9 steuern wir die Bindestriche und entfernen den Index- / Offset-Zähler, dem jede Zeile "out" vorangestellt ist.

Das Ergebnis ist ein Muster von 8-4-4-4-12 Kleinbuchstaben a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

13
2017-08-25 23:57



Brillant! nur eine einzige Zeile ohne Abhängigkeiten, BSD / macOS kompatibel ... großartig - dinigo
Tun NICHT benutze "Schwanz -1". Wenn Sie nur "od -x / dev / urandom" selbst ausführen, geht es endlos weiter und produziert kontinuierlich mehr Zeilen mit zufälligen Daten. "tail -1" kann einfach nur da sitzen und immer auf die "letzte" Zeile warten. Ansonsten ist es eine gute Lösung. - UncaAlby
Bitte beachten Sie, dass das Ende nur in der "Erklärung" als optionaler Parameter steht, wenn die Anzahl der vom Kopf ausgegebenen Zeilen größer als eins ist. Dort soll der Empfang einer einzelnen Zeile von 16 Bytes durch awk sichergestellt werden, und ist nicht Teil des ursprünglichen Befehls. Das Rohr, das von od abgeht, bereinigt bereits den Ausgang für die Rohrleitung bis zum Ende -1. Nach meiner Erfahrung ist der einzige Zeitpunkt, an dem das Tail für immer wartet, ein Argument -f. Ich entschuldige mich, wenn die Erklärung nicht klar war, wo es die Verwendung von Schwanz -1 nur notwendig ist, wenn der Ausgang des Kopfes mehr als eine Linie produziert. - dan
Tun nicht Verwenden Sie dies, es verletzt vollständig die UUID-Spezifikation. Nur UUID der Version 4 dürfen so zufällig sein. - jlh
@ jlh Ich bin nicht sicher, warum diese Frage gesperrt wurde, aber hier ist eine feste Version, die diesen Ansatz UUID-v4-konform macht: 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


Nur so fühlt sich Python nicht ausgeschlossen:

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

Um es in der Shell zu verwenden:

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

Siehe die Python-Dokumentation UUID für die Arten von UUIDS, die erzeugt werden können.

Um eine systemd machine-id-kompatible Datei auf einer Nicht-System-Maschine zu generieren, könnten Sie Python verwenden, um es auf diese Weise zu machen:

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

12
2018-01-16 15:26





Perl stellt eine UUID-Bibliothek basierend auf der e2fsprogs Paket. Auf meinem Debian-System ist es das libuuid-perl Paket. Hier ist ein Beispiel für einen Einzeiler; sehen man uuid für mehr:

$ 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

Dies wäre trivial, um ein Shellscript mit Backticks oder hinzuzufügen $() Notation:

#!/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 - Hilf mir sehr! - rafa.ferreira