Pregunta ¿Cómo crear un UUID en bash?


En Java es posible crear un aleatorio. UUID:

UUID uuid = UUID.randomUUID();

¿Cómo hacer esto en Bash?


163
2018-01-16 13:41


origen




Respuestas:


Ver el uuidgen programa que es parte de la e2fsprogs paquete.

De acuerdo a esta, libuuid ahora es parte de util-linux y la inclusión en e2fsprogs se está eliminando gradualmente. Sin embargo, en los nuevos sistemas de Ubuntu, uuidgen ahora está en el uuid-runtime paquete.

Para crear un uuid y guardarlo en una variable:

uuid=$(uuidgen)

En mi sistema Ubuntu, los caracteres alfa se muestran en minúsculas y en mi sistema OS X, se muestran en mayúsculas (gracias a David por señalar esto en un comentario).

Para cambiar a mayúsculas (después de generarlo como se indica arriba):

uuid=${uuid^^}

Para cambiar a minúsculas:

uuid=${uuid,,}

Si, por ejemplo, tiene dos UUID y desea compararlos en Bash, ignorando su caso, puede hacer una tolower() comparación de estilo como este:

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

185
2018-01-16 14:01



¡Oye, no es justo! mis e2fsprogs no vinieron con eso! quiero uno, donde lo consigo? (actualización: ahhh ... debian lo mete en el uuid-runtime paquete sin razón aparente ... +1 para usted) - quack quixote
uuidgen viene incorporado en freeBSD. no siempre está en el paquete e2fsprogs. - Good Person
@Rob: Para responder a tu pregunta original, es para etiquetas de unidad. - Dennis Williamson
Noté que uuidgen en Mac emite en mayúsculas mientras que en Ubuntu (uuidgen de util-linux 2.20.1) en minúsculas. ¿Por qué la diferencia? También se enumeró Ubuntu de dónde provino la herramienta, pero en Mac, no hay información de versión ni de qué paquete proviene. - David
@David: creo que es parte del sistema operativo base en OS X. No tengo idea de por qué uno es mayúscula y el otro es menor. Realmente no importa ya que cualquiera representa caracteres hexadecimales válidos (echo -e 'f\nF' | grep '[[:xdigit:]]' salidas de ambas lineas). Si es importante para usted y tiene Bash 4, puede hacer esto en minúsculas: uuid=$(uuidgen); uuid=${uuid,,}o esto para que sea mayúscula: uuid=$(uuidgen); uuid=${uuid^^} o algo por el estilo para hacer una tolower() prueba de estilo: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


Para agregar variedad sin agregar dependencias externas, en Linux tu puedes hacer:

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

Para propagar malas prácticas, en FreeBSD, bajo la capa de compatibilidad de linux (linuxulator?),

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

Referencias:


128
2017-08-07 12:55



Esto es impresionante - Tom O'Connor
Esto debe evitarse ya que es altamente no portátil (aunque FreeBSD suministra / compat / linux / proc / sys / kernel / random / uuid para aplicaciones mal escritas) - Good Person
Se ajusta perfectamente para uso dentro de la imagen initrd - Maximilian
El método FreeBSD no parece estar en Mac OS X (ni en el método Linux). Al menos uuidgen parece estar preinstalado en la Mac (o se instaló con otra cosa que instalé). - David
Esta es una mejor respuesta para configuraciones realmente mínimas, como un contenedor Docker. - jacderida


Sólo por estar completo ... También hay un generador UUID instalado con el dbus paquete en Debian. Me lo perdí mirando alrededor. Probablemente sea el mismo algoritmo que el paquete e2fsprogs, pero no agrega los guiones, por lo que podría ser un poco más limpio para usted:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity agrega un consejo de seguridad: "Los UUID DBus no están relacionados ni son compatibles con RFC 4122. Además, dbus-uuidgen Siempre usa la marca de tiempo de Unix como los últimos 4 bytes. Así que pueden ser inadecuados para algunos usos "(Gracias, Grawity, debería haberlo visto en la página del manual).


28
2018-01-16 14:18



Los UUID de DBus no están relacionados ni son compatibles con RFC 4122. Además, dbus-uuidgen Siempre usa la marca de tiempo de Unix como los últimos 4 bytes. Por lo que pueden ser inadecuados para algunos usos. - grawity
Lo mismo funciona en Fedora-25, también ... - kmonsoor


Si no desea depender de otros ejecutables, o no puede usarlos, aquí está la versión de bash pura de aquí:

# 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



los T variable puede ser eliminada y la for T el bucle se puede cambiar a: case $N in 3 | 5 | 7 | 9) printf '-';; esac (desglosado en líneas separadas si se prefiere). - Dennis Williamson
Agregué un comentario al código en el enlace de github que muestra una versión usando case para eliminar el if declaraciones, así como el interior for declaración. Hace el código mucho más limpio. Tenga en cuenta que ambos B%15 debiera ser B%16 y B%255 debiera ser B%256. - Dennis Williamson


He encontrado este script "one-liner" útil cuando uuidgen no está disponible. Esto también evita cualquier necesidad de instalar módulos externos para Perl o Python.

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

Probado en SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 y más recientemente con éxito. Tengo curiosidad por si esto es propenso a la no singularidad, pero no he sido "mordido" en los últimos 10 años. Por supuesto, head -1 podría ser reemplazado con head -_other-value_ | tail -1 también.

Para explicar,

/dev/random y /dev/urandom Son generadores al azar del núcleo.

od (volcado octal) tiene un interruptor de salida hexadecimal (-x) que produce 16 bytes por línea.

head -n [| cola -1] (donde n> 0) extrae solo una línea de la salida anterior.

awk establece el OutputFieldSeparator para que sea un guión en todos los lugares en que aparezca una coma en la declaración de impresión. Al especificar los campos 2-9 de forma independiente, controlamos los guiones y eliminamos el contador de índice / desplazamiento que 'od' prefija cada línea de salida con.

El resultado es un patrón de 8-4-4-4-12 caracteres minúsculos a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

13
2017-08-25 23:57



¡Brillante! solo una línea sin dependencias, compatible con BSD / macOS ... genial - dinigo
Hacer NO utilizar "cola -1". Si ejecuta solo "od -x / dev / urandom" por sí mismo, continúa indefinidamente, produciendo continuamente más líneas de datos aleatorios. "cola -1" puede quedarse allí esperando la "última" línea. De lo contrario, es una buena solución. - UncaAlby
Tenga en cuenta que la cola solo se encuentra en la "explicación" como parámetro opcional cuando el número de líneas emitidas por encabezado es mayor que uno. Ahí, para garantizar que se reciba una sola línea de 16 bytes por awk, y no forma parte del comando original. La tubería a la cabeza de od ya desinfecta la salida de la tubería a la cola -1. En mi experiencia, la única cola de tiempo que espera para siempre es con un argumento -f. Pido disculpas si la explicación no fue clara donde se indica que el uso de la cola -1 solo es necesario cuando la salida de la cabeza produce más de una línea. - dan
Hacer no usar esto, viola completamente la especificación UUID. Solo la versión 4 de UUID puede ser aleatoria de esta manera. - jlh
@jlh No estoy seguro de por qué esta pregunta estaba bloqueada, pero aquí hay una versión fija que hace que este enfoque sea compatible con 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


Solo para que Python no se sienta excluido:

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

Para usarlo en la concha:

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

Ver el Documentación Python UUID Para los tipos de UUIDS que se pueden generar.

Para generar un archivo compatible con id. De máquina de systemd en una máquina que no sea systemd, puede usar python para hacerlo de esta manera:

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

12
2018-01-16 15:26





Perl proporciona una biblioteca UUID basada en el e2fsprogs paquete. En mi sistema Debian es el libuuid-perl paquete. Aquí hay un ejemplo de una sola línea; ver man uuid para más:

$ 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

Esto sería trivial para agregar a un shellscript con backticks o $() notación:

#!/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 - ¡Ayúdame mucho! - rafa.ferreira


apt-get install uuid

Trabajó para mí, entonces la identificación corrió uuid


3
2018-06-19 09:07





Escribí una pequeña función Bash usando Python para generar un número arbitrario de UUID en masa:

# 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 prefieres en minúsculas, cambia:

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

A:

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

1
2017-08-03 22:16





Por favor, mire la biblioteca UUID OSSP (http://www.ossp.org/pkg/lib/uuid/), y considere instalarlo. Algunos proyectos lo ofrecen como una opción (por ejemplo, PostgreSQL). Maneja adecuadamente los UUIDs de la versión 3 y la versión 5, que estaba más allá de lo que mi biblioteca instalada (por ejemplo, e2fsprogs) podía manejar. Afortunadamente, openSUSE lo tiene en uno de los repositorios principales. Hacer que una versión funcione con Windows (por ejemplo, Cygwin) o MySQL ha sido un problema. Parece que es hora de cambiar a Linux / PostgreSQL / Python (y me encantó la GUI de SQLyog para MySQL / MariaDB) ya que realmente necesito los UUID v3 y v5.


1
2017-09-23 23:37



De acuerdo completamente! Para mi caso de uso, fue perfecto, ya que también admite espacios de nombres a través del -v3 ns:URL custom-data mecanismo de siembra. - Roberto Andrade


Estoy seguro de que algunos llegarán aquí, y solo están buscando una manera fácil de generar una ID única para usar en sus scripts, y no es necesario que sea un verdadero UUID.

Si es así, puedes hacer lo siguiente, lo que generará un ID que será único hasta el segundo, así que si lo ejecutas varias veces en un segundo, obtendrás el mismo resultado.

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

generará identificadores como los siguientes basados ​​en la hora actual del sistema:

U1454423662

NOTA: Si está en Linux, o tiene Coreutils instalado en un mac, entonces puede usar lo siguiente para generar una identificación única para el nanosegundo:

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

o si prefiere una solución basada en python hasta el nanosegundo, que debería funcionar en casi todas partes, ejecute:

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

1
2018-02-02 14:38



Esto es en general una muy mala práctica. Las computadoras modernas son perfectamente capaces de ejecutar muchas cosas en paralelo y completar tareas en serie rápidamente, pero esta identificación será idéntica para cualquier invocación que esté dentro de un segundo de otra. Por no mencionar otros equipos que ejecutan este script al mismo tiempo. Una opción mejor, pero todavía no grande sería mktemp -u como en MYID="$(mktemp -u)". Si puede permitirse tener archivos temporales vacíos por ahí hasta que reinicie, suelte el -u: MYID="$(mktemp)" - Chris Harrington
Hey ... buenos puntos en el único único para el segundo punto ... Agregaré algunas notas arriba ... - Brad Parks