Question Comment créer un UUID dans bash?


En Java, il est possible de créer une liste aléatoire. UUID:

UUID uuid = UUID.randomUUID();

Comment faire cela dans Bash?


163
2018-01-16 13:41


origine




Réponses:


Voir le uuidgen programme qui fait partie de la e2fsprogs paquet.

Selon ce, libuuid fait maintenant partie de util-linux et l'inclusion dans e2fsprogs est en cours de suppression. Cependant, sur les nouveaux systèmes Ubuntu, uuidgen est maintenant dans le uuid-runtime paquet.

Pour créer un uuid et le sauvegarder dans une variable:

uuid=$(uuidgen)

Sur mon système Ubuntu, les caractères alpha sont écrits en minuscule et sur mon système OS X, ils sont en majuscule (merci à David de l'avoir signalé dans un commentaire).

Pour passer à toutes les majuscules (après les avoir générées comme ci-dessus):

uuid=${uuid^^}

Pour basculer vers tous les minuscules:

uuid=${uuid,,}

Si, par exemple, vous avez deux UUID et que vous souhaitez les comparer dans Bash, en ignorant leur cas, vous pouvez effectuer une tolower() comparaison de style comme ceci:

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

185
2018-01-16 14:01



hé, pas juste! mes e2fsprogs ne sont pas venus avec ça! J'en veux un, où puis-je l'obtenir? (mise à jour: ahhh ... Debian le colle dans le uuid-runtime forfait sans raison apparente ... +1 pour vous) - quack quixote
uuidgen est intégré à freeBSD. ce n'est pas toujours dans le paquet e2fsprogs. - Good Person
@Rob: Pour répondre à votre question initiale, c'est pour étiquettes de lecteur. - Dennis Williamson
Je remarque que uuidgen sur Mac émet en majuscule tandis que sur Ubuntu (uuidgen à partir de util-linux 2.20.1) en minuscule. Pourquoi la différence? Ubuntu a également répertorié l’origine de l’outil, mais sur Mac, il n’ya pas d’informations sur la version ni sur le paquet dont il provient. - David
@ David: Je pense que cela fait partie du système d'exploitation de base sous OS X. Je ne sais pas pourquoi l'une est en majuscule et l'autre est plus basse. Cela n’a pas vraiment d’importance puisque l’un ou l’autre représente des caractères hexadécimaux validesecho -e 'f\nF' | grep '[[:xdigit:]]' sort les deux lignes). Si cela a de l'importance pour vous et que vous avez Bash 4, vous pouvez le faire pour le rendre en minuscule: uuid=$(uuidgen); uuid=${uuid,,}ou ceci pour le mettre en majuscule: uuid=$(uuidgen); uuid=${uuid^^} ou quelque chose du genre pour faire une tolower() test de style: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


Pour ajouter de la variété sans ajouter de dépendances externes, sur Linux tu peux faire:

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

Propager de mauvaises pratiques, sur FreeBSD, sous la couche de compatibilité linux (linuxulator?),

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

Références:


128
2017-08-07 12:55



C'est génial. - Tom O'Connor
Ceci devrait être évité car il est très peu portable (bien que FreeBSD fournisse / compat / linux / proc / sys / kernel / random / uuid pour des applications mal écrites) - Good Person
Il convient parfaitement pour une utilisation à l'intérieur de initrd image - Maximilian
La méthode FreeBSD ne semble pas être sur Mac OS X (ni la méthode Linux). Au moins, uuidgen semble être préinstallé sur le Mac (ou a été installé avec quelque chose d’autre que j’ai installé). - David
C'est une meilleure réponse pour des configurations vraiment minimales, comme un conteneur Docker. - jacderida


Juste pour être complet ... Il y a aussi un générateur d'UUID installé avec le dbus paquet sur Debian. Je l'ai raté en regardant autour de moi plus tôt. C'est probablement le même algorithme que le paquet e2fsprogs, mais il n'ajoute pas les tirets, il pourrait donc être un peu plus propre pour vous:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity ajoute un conseil de sécurité: "Les UUID de DBus ne sont pas liés ou compatibles avec RFC 4122. Outre, dbus-uuidgen utilise toujours l’horodatage Unix comme les 4 derniers octets. Donc, ils pourraient ne pas convenir à certaines utilisations. "(Merci, Grawity, j'aurais dû le remarquer dans la page de manuel.)


28
2018-01-16 14:18



Les UUID de DBus ne sont ni liés ni compatibles avec la RFC 4122. En outre, dbus-uuidgen utilise toujours l’horodatage Unix comme les 4 derniers octets. Ils pourraient donc ne pas convenir à certaines utilisations. - grawity
même fonctionne sur Fedora-25, aussi ... - kmonsoor


Si vous ne voulez pas dépendre d'autres exécutables, ou si vous ne pouvez pas les utiliser, voici la version pure bash de ici:

# 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



le T variable peut être éliminée et la for T boucle peut être changé en: case $N in 3 | 5 | 7 | 9) printf '-';; esac (éclaté sur des lignes séparées si vous préférez). - Dennis Williamson
J'ai ajouté un commentaire au code sur le lien github montrant une version utilisant case éliminer le if déclarations ainsi que l'intérieur for déclaration. Cela rend le code beaucoup plus ordonné. Notez que les deux B%15 devrait être B%16 et B%255 devrait être B%256. - Dennis Williamson


J'ai trouvé ce script "one-liner" utile là où uuidgen n'est pas disponible. Cela évite également l’installation de modules externes pour Perl ou Python.

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

Testé avec succès sur SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 et plus récent. Je suis curieux de savoir si cela est sujet à la non-unicité, mais je n’ai pas été «mordu» au cours des 10 dernières années. Bien sûr, head -1 pourrait être remplacé par head -_other-value_ | tail -1 aussi.

Expliquer,

/dev/random et /dev/urandom sont des générateurs aléatoires du noyau.

od (octal dump) a un commutateur de sortie hexadécimale (-x) produisant 16 octets par ligne.

head -n [| tail -1] (où n> 0) extrait une seule ligne de la sortie précédente.

awk définit OutputFieldSeparator comme un trait d'union chaque fois qu'une virgule apparaît dans l'instruction d'impression. En spécifiant indépendamment les champs 2 à 9, nous contrôlons les traits d'union et supprimons le compteur d'index / décalage avec lequel 'od' préfixe chaque ligne de sortie.

Le résultat est un motif de 8-4-4-4-12 caractères minuscules a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

13
2017-08-25 23:57



Brillant! juste une seule ligne sans dépendance, compatible BSD / macOS ... super - dinigo
Faire NE PAS utilisez "queue -1". Si vous exécutez simplement "od -x / dev / urandom", cela continue indéfiniment, en produisant continuellement plus de lignes de données aléatoires. "tail -1" peut rester assis là pour toujours en attendant la "dernière" ligne. Sinon, c'est une bonne solution. - UncaAlby
Veuillez noter que tail est uniquement dans "l'explication" en tant que paramètre facultatif lorsque le nombre de lignes sorties par head est supérieur à un. Là pour assurer la réception d'une seule ligne de 16 octets par awk, et ne fait pas partie de la commande d'origine. Le tuyau à partir de od assainit déjà la sortie pour tuyauterie à queue -1. D'après mon expérience, le seul temps d'attente pour toujours est avec un argument -f. Je m'excuse si l'explication n'était pas claire là où il est indiqué que l'utilisation de la queue -1 n'est nécessaire que lorsque la sortie de la tête produit plus d'une ligne. - dan
Faire ne pas utilisez ceci, cela violerait complètement la spécification UUID. Seule la version 4 des UUID est autorisée à être aléatoire de la sorte. - jlh
@jlh Je ne sais pas pourquoi cette question a été verrouillée, mais voici une version corrigée qui rend cette approche compatible avec 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


Juste pour que le python ne se sente pas exclu:

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

Pour l'utiliser dans le shell:

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

Voir le UUID de la documentation Python pour les types d'UUIDS pouvant être générés.

Pour générer un fichier compatible d'identifiant de machine systemd sur une machine autre que systemd, vous pouvez utiliser python pour le faire de cette façon:

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

12
2018-01-16 15:26





Perl fournit une bibliothèque UUID basée sur le e2fsprogs paquet. Sur mon système Debian, c’est le libuuid-perl paquet. Voici un exemple one-liner; voir man uuid pour plus:

$ 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

Ce serait trivial d'ajouter à un shellscript avec backticks ou $() 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 - Aidez-moi beaucoup! - rafa.ferreira


apt-get install uuid

Travaillé pour moi, alors id a couru uuid


3
2018-06-19 09:07





J'ai écrit une petite fonction Bash en utilisant Python pour générer un nombre arbitraire d'UUID en bloc:

# 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"')]))'
}

Si vous préférez les minuscules, changez:

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

À:

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

1
2017-08-03 22:16





Veuillez consulter la bibliothèque UUID OSSP (http://www.ossp.org/pkg/lib/uuid/) et envisagez de l’installer. Certains projets l’offrent en option (par exemple, PostgreSQL). Il gère correctement les UUID des versions 3 et 5, ce qui était au-delà de ce que ma bibliothèque installée (par exemple, e2fsprogs) pouvait gérer. Heureusement, openSUSE l’a dans l’un des principaux dépôts. Faire fonctionner une version avec Windows (par exemple Cygwin) ou MySQL a été un fléau. On dirait qu'il est temps de passer à Linux / PostgreSQL / Python (et j'ai tellement adoré l'interface graphique SQLyog pour MySQL / MariaDB) car j'ai vraiment besoin des UUID v3 et v5.


1
2017-09-23 23:37



Complètement d'accord! Pour mon cas d’utilisation, c’était parfait, car il prend également en charge le namespacing via -v3 ns:URL custom-data mécanisme de semis. - Roberto Andrade


Je suis sûr que certains vont arriver ici et cherchent simplement un moyen simple de générer un identifiant unique à utiliser dans leurs scripts. Il n'est pas nécessaire que ce soit un véritable UUID.

Si tel est le cas, vous pouvez simplement procéder comme suit, ce qui générera un identifiant unique à la seconde près. Ainsi, si vous l'exécutez plusieurs fois par seconde, vous obtiendrez toujours le même résultat.

MYID="U$(date +%s)"
echo $MYID

générera des identifiants comme ceux suivants basés sur l’heure système actuelle:

U1454423662

REMARQUE: Si vous êtes sous Linux ou que Coreutils est installé sur un mac, vous pouvez utiliser ce qui suit pour générer un identifiant unique à la nanoseconde:

MYID="U$(date +%s%N)"
echo $MYID

ou si vous préférez une solution à base de python jusqu'à la nanoseconde, qui devrait fonctionner presque partout, lancez:

MYUID=U$(python -c'import time; print repr(time.time())')
echo $MYUID

1
2018-02-02 14:38



C’est dans l’ensemble une très mauvaise pratique. Les ordinateurs modernes sont parfaitement capables d’exécuter beaucoup de choses en parallèle et d’accomplir rapidement des tâches série, mais cet ID sera identique pour tous les appels qui se situent à une seconde près. Sans parler des autres ordinateurs exécutant ce script en même temps. Une option meilleure mais toujours pas excellente serait mktemp -u un péché MYID="$(mktemp -u)". Si vous pouvez vous permettre d’avoir des fichiers temporaires vides jusqu’au redémarrage, lâchez le bouton -u: MYID="$(mktemp)" - Chris Harrington
Hé ... bons points sur l'unique unique au deuxième point ... Je vais ajouter quelques notes ci-dessus ... - Brad Parks