web-dev-qa-db-fra.com

Comment créer un UUID dans bash?

Dans Java il est possible de créer un aléatoire UUID :

UUID uuid = UUID.randomUUID();

Comment faire cela dans Bash?

185
raoulsson

Voir le programme uuidgen qui fait partie du package e2fsprogs .

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

Pour créer un uuid et l'enregistrer dans une variable:

uuid=$(uuidgen)

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

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

uuid=${uuid^^}

Pour passer à tous les minuscules:

uuid=${uuid,,}

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

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

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

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

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

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

Références:

167
Samveen

Par souci d'exhaustivité ... Il y a aussi un générateur UUID installé avec le paquet dbus sur Debian. Je l'ai raté en regardant autour plus tôt. C'est probablement le même algorithme que le paquet e2fsprogs, mais il n'ajoute pas les tirets, donc il pourrait ê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 DBus ne sont pas liés ou compatibles avec RFC 4122 . En outre, dbus-uuidgen utilise toujours l'horodatage Unix comme 4 derniers octets. Donc ils pourraient ne pas convenir à certaines utilisations. " (Merci, Grawity, j'aurais dû repérer cela dans la page de manuel.)

34
quack quixote

Si vous ne voulez pas dépendre d'autres exécutables, ou si vous ne pouvez pas les utiliser, voici la version bash pure 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
20
noway

J'ai trouvé ce script "one-liner" utile là où uuidgen n'est pas disponible. Cela contourne également toute nécessité d'installer des 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 (vidage octal) possède un commutateur de sortie hexadécimal (-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 le OutputFieldSeparator comme un trait d'union partout où une virgule se produit dans l'instruction print. En spécifiant les champs 2 à 9 indépendamment, nous contrôlons les tirets et supprimons le compteur d'index/décalage avec lequel "od" préfixe chaque ligne de sortie.

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

993bb8d7-323d-b5ee-db78-f976a59d8284
19
dan

Juste python ne se sent 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 ID de la documentation Python pour les types d'UUIDS qui peuvent être générés.

Pour générer un fichier compatible avec l'ID machine systemd sur une machine non 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
14
davey

Perl fournit une bibliothèque UUID basée sur le package e2fsprogs. Sur mon système Debian, c'est le paquet libuuid-Perl. Voici un exemple de doublure; voir man uuid pour en savoir 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 à ajouter à un shellscript avec des backticks ou une 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
quack quixote
apt-get install uuid

J'ai travaillé pour moi, puis j'ai exécuté uuid

3
Joseph

Je suis sûr que certains arriveront ici et recherchent simplement un moyen facile de générer un ID unique à utiliser dans leurs scripts, et il n'est pas nécessaire que ce soit un véritable UUID.

Si c'est le cas, vous pouvez simplement faire ce qui suit, ce qui générera un identifiant unique jusqu'à la seconde - donc si vous l'exécutez plusieurs fois en une seconde, vous obtiendrez toujours le même résultat.

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

générera des identifiants comme les suivants en fonction de l'heure actuelle du système:

U1454423662

REMARQUE: Si vous êtes sous Linux ou si 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 basée sur python jusqu'à la nanoseconde, qui devrait fonctionner presque partout, exécutez:

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

Ce fil, avec ses exemples variés, m'a été très utile. J'ai souvent besoin de fonctions uuid dans un certain nombre d'environnements différents. Et bien que j'aime les exemples de bash purs, il est parfois plus pratique d'utiliser une bibliothèque d'une langue différente.

Donc, juste pour la rigueur, Ruby (1.9.3+) a le module SecureRandom intégré contenant un certain nombre de fonctions de hachage et d’identification utiles. Depuis le bash cli, vous pouvez le faire.

Ruby -r securerandom -e 'puts SecureRandom.uuid'
1
wbr

Veuillez consulter la bibliothèque OSSP UUID ( http://www.ossp.org/pkg/lib/uuid/ ) et envisager de l'installer. Certains projets le proposent 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 référentiels principaux. Faire fonctionner une version avec Windows (par exemple Cygwin) ou MySQL a été un fléau. Il semble qu'il soit temps de passer à Linux/PostgreSQL/Python (et j'ai tellement aimé l'interface graphique SQLyog vers MySQL/MariaDB) car j'ai vraiment besoin d'UUID v3 et v5.

1
user2351170

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

# 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
Will
ran=`od -X -A n /dev/random | head -1 | cut -c3-38`

correlation_id=`echo ${ran} | cut -c1-8`-`echo ${ran} | cut -c10-13`-`echo ${ran} | cut -c14-17`-`echo ${ran} | cut -c19-22`-`echo ${ran} | cut -c23-26``echo ${ran} | cut -c28-35`
0
andyfff