unix - script - shell linux que es
Genera un nombre de archivo aleatorio en el shell de Unix (12)
Me gustaría generar un nombre de archivo aleatorio en shell unix (por ejemplo, tcshell). El nombre del archivo debe consistir en 32 letras hexadecimales al azar, por ejemplo:
c7fdfc8f409c548a10a0a89a791417c5
(a lo cual agregaré lo que sea necesario). El punto es poder hacerlo solo en shell sin recurrir a un programa.
¡Probado en zsh, debería funcionar con cualquier shell compatible con BASH!
#!/bin/zsh
SUM=`md5sum <<EOF
$RANDOM
EOF`
FN=`echo $SUM | awk ''// { print $1 }''`
echo "Your new filename: $FN"
Ejemplo:
$ zsh ranhash.sh
Your new filename: 2485938240bf200c26bb356bbbb0fa32
$ zsh ranhash.sh
Your new filename: ad25cb21bea35eba879bf3fc12581cc9
Como probablemente haya notado en cada una de las respuestas, generalmente debe "recurrir a un programa".
Sin embargo, sin usar ningún ejecutable externo , en Bash y ksh:
for i in {0..31}; do string+=$(printf "%x" $(($RANDOM%16)) ); done; echo $string
en zsh:
for i in {0..31}; do string+=$(printf "%x" $(($RANDOM%16)) ); dummy=$RANDOM; done; echo $string
Tenga en cuenta que debido al uso del operador de mod en un valor que va de 0 a 32767, la distribución de los dígitos que utilizan los fragmentos anteriores estará sesgada (sin mencionar el hecho de que los números son pseudoaleatorios en primer lugar).
En cualquier caso, la forma correcta de hacerlo es usar mktemp
como en la respuesta de oraz .
Espero agregar una (tal vez) mejor solución a este tema.
Aviso: esto solo funciona con bash4
y algunos implementos de mktemp
(por ejemplo, el de GNU)
Prueba esto
fn=$(mktemp -u -t ''XXXXXX'')
echo ${fn///tmp///}
Este es dos veces más rápido que head /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
head /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
head /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
, y ocho veces más rápido que cat /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
cat /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
cat /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
.
Punto de referencia:
Con mktemp:
#!/bin/bash
# a.sh
for (( i = 0; i < 1000; i++ ))
do
fn=$(mktemp -u -t ''XXXXXX'')
echo ${fn///tmp///} > /dev/null
done
time ./a.sh
./a.sh 0.36s user 1.97s system 99% cpu 2.333 total
Y el otro:
#!/bin/bash
# b.sh
for (( i = 0; i < 1000; i++ ))
do
cat /dev/urandom | tr -dc ''a-zA-Z0-9'' | head -c 32 > /dev/null
done
time ./b.sh
./b.sh 0.52s user 20.61s system 113% cpu 18.653 total
Esta respuesta es muy similar a las marcas, por lo que realmente no me puedo atribuir el mérito, pero las combinaciones de comandos cat y tr fueron bastante lentas, y encontré esta versión bastante más rápida. Necesitas hexdump.
hexdump -e ''/1 "%02x"'' -n32 < /dev/urandom
La primera respuesta es buena, pero ¿por qué tenedor gato si no es necesario.
tr -dc ''a-f0-9'' < /dev/urandom | head -c32
Otra cosa que puede agregar es ejecutar el comando de fecha de la siguiente manera:
date +%S%N
Lee en un segundo y el resultado agrega mucha aleatoriedad.
Otra forma más [tm].
R=$(echo $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM | md5 | cut -c -8)
FILENAME="abcdef-$R"
Si está en Linux, Python vendrá preinstalado. Así que puedes buscar algo similar a lo siguiente:
python -c "import uuid; print str(uuid.uuid1())"
Si no te gustan los guiones, utiliza la función de reemplazar como se muestra a continuación
python -c "import uuid; print str(uuid.uuid1()).replace(''-'','''')"
Suponiendo que está en un linux, lo siguiente debería funcionar:
cat /dev/urandom | tr -cd ''a-f0-9'' | head -c 32
Esto es solo pseudoaleatorio si su sistema tiene poca entropía, pero está (en Linux) garantizado que terminará. Si necesita datos genuinamente aleatorios, cat /dev/random
lugar de /dev/urandom
. Este cambio hará que tu código se bloquee hasta que haya suficiente entropía disponible para producir una salida verdaderamente aleatoria, por lo que puede ralentizar tu código. Para la mayoría de los usos, la salida de /dev/urandom
es suficientemente aleatoria.
Si tiene OS X u otro BSD, debe modificarlo a lo siguiente:
cat /dev/urandom | env LC_CTYPE=C tr -cd ''a-f0-9'' | head -c 32
Tome 16 bytes de /dev/random
, conviértalos a hex, tome la primera línea, elimine la dirección, elimine los espacios.
head /dev/random -c16 | od -tx1 -w16 | head -n1 | cut -d'' '' -f2- | tr -d '' ''
Asumir que "sin recurrir a un programa" significa "usar solo programas que están disponibles", por supuesto.
Un comando, sin tubería, sin bucle:
hexdump -n 16 -v -e ''/1 "%02X"'' -e ''/16 "/n"'' /dev/urandom
Si no necesita la línea nueva, por ejemplo, cuando la usa en una variable:
hexdump -n 16 -v -e ''/1 "%02X"'' /dev/urandom
El uso de "16" genera 32 dígitos hexadecimales.
por qué no usar el comando mixtemp de unix:
$ TMPFILE=`mktemp tmp.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` && echo $TMPFILE
tmp.MnxEsPDsNUjrzDIiPhnWZKmlAXAO8983