Pertanyaan Bagaimana cara membuat UUID di bash?


Di Jawa adalah mungkin untuk membuat acak UUID:

UUID uuid = UUID.randomUUID();

Bagaimana melakukan ini di Bash?


163
2018-01-16 13:41






Jawaban:


Lihat uuidgen program yang merupakan bagian dari e2fsprogs paket.

Menurut ini, libuuid sekarang bagian dari util-linux dan inklusi dalam e2fsprogs sedang dihapus. Namun, pada sistem Ubuntu baru, uuidgen sekarang di uuid-runtime paket.

Untuk membuat uuid dan menyimpannya dalam sebuah variabel:

uuid=$(uuidgen)

Pada sistem Ubuntu saya, karakter alfa dikeluarkan sebagai huruf kecil dan pada sistem OS X saya, mereka adalah output sebagai huruf besar (terima kasih kepada David untuk menunjukkan ini dalam komentar).

Untuk beralih ke semua huruf besar (setelah membuatnya seperti di atas):

uuid=${uuid^^}

Untuk beralih ke semua huruf kecil:

uuid=${uuid,,}

Jika, misalnya, Anda memiliki dua UUID dan Anda ingin membandingkannya dengan Bash, mengabaikan kasusnya, Anda dapat melakukan tolower() Perbandingan gaya seperti ini:

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

185
2018-01-16 14:01



hei, tidak adil! e2fsprog saya tidak datang dengan itu! saya mau satu, dimana saya mendapatkannya? (update: ahhh ... debian menempel di uuid-runtime paket tanpa alasan yang jelas ... +1 untuk Anda) - quack quixote
uuidgen hadir di dalam FreeBSD. itu tidak selalu dalam paket e2fsprogs. - Good Person
@Rob: Untuk menjawab pertanyaan asli Anda, itu untuk label drive. - Dennis Williamson
Saya melihat uuidgen pada Mac memancarkan dalam semua huruf besar sementara di Ubuntu (uuidgen dari util-linux 2.20.1) dalam semua huruf kecil. Kenapa bedanya? Juga Ubuntu terdaftar di mana alat itu berasal tetapi di Mac, tidak ada info versi atau dari paket mana asalnya. - David
@ David: Saya percaya itu bagian dari sistem operasi dasar pada OS X. Saya tidak tahu mengapa yang satu adalah huruf besar dan yang lain lebih rendah. Tidak terlalu penting karena keduanya mewakili karakter hex yang valid (echo -e 'f\nF' | grep '[[:xdigit:]]' menghasilkan kedua baris). Jika itu penting untuk Anda dan Anda memiliki Bash 4, Anda dapat melakukan ini untuk menjadikannya huruf kecil: uuid=$(uuidgen); uuid=${uuid,,} atau ini untuk menjadikannya huruf besar: uuid=$(uuidgen); uuid=${uuid^^} atau sesuatu di sepanjang jalur ini untuk melakukan tolower() tes gaya: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


Untuk menambah variasi tanpa menambahkan dependensi eksternal, aktif Linux Anda dapat melakukan:

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

Untuk menyebarkan praktik buruk, aktif FreeBSD, di bawah lapisan kompatibilitas linux (linuxulator?),

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

Referensi:


128
2017-08-07 12:55



Ini luar biasa. - Tom O'Connor
Ini harus dihindari karena sangat tidak portabel (meskipun persediaan FreeBSD / compat / linux / proc / sys / kernel / acak / uuid untuk aplikasi yang ditulis dengan buruk) - Good Person
Ini sangat cocok untuk penggunaan di dalam gambar initrd - Maximilian
Metode FreeBSD tidak muncul di Mac OS X (atau metode Linux). Setidaknya uuidgen tampaknya sudah diinstal pada Mac (atau diinstal dengan sesuatu yang lain yang saya instal). - David
Ini adalah jawaban yang lebih baik untuk setup yang sangat minim, seperti kontainer Docker. - jacderida


Hanya demi kelengkapan ... Ada juga generator UUID diinstal dengan dbus paket di Debian. Aku merindukannya melihat-lihat sebelumnya. Ini mungkin algoritma yang sama dengan paket e2fsprogs, tetapi tidak menambahkan tanda hubung, jadi mungkin sedikit lebih bersih untuk Anda:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity menambahkan tip keamanan: "DBus UUID tidak terkait atau tidak kompatibel dengan RFC 4122. Selain, dbus-uuidgen selalu menggunakan stempel waktu Unix sebagai 4 byte terakhir. Jadi mereka mungkin tidak cocok untuk beberapa penggunaan. "(Terima kasih, Grawity, saya seharusnya melihat itu di halaman manual.)


28
2018-01-16 14:18



DBUS UUID tidak terkait atau kompatibel dengan RFC 4122. Selain itu, dbus-uuidgen selalu menggunakan stempel waktu Unix sebagai 4 byte terakhir. Jadi mereka mungkin tidak cocok untuk beberapa penggunaan. - grawity
karya yang sama pada Fedora-25, juga ... - kmonsoor


Jika Anda tidak ingin bergantung pada executable lain, atau Anda tidak dapat menggunakannya, ini adalah versi bash murni dari sini:

# 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



Itu T variabel dapat dihilangkan dan for T lingkaran dapat diubah menjadi: case $N in 3 | 5 | 7 | 9) printf '-';; esac (pecah pada baris terpisah jika disukai). - Dennis Williamson
Saya menambahkan komentar ke kode di tautan github yang menunjukkan versi menggunakan case untuk menghilangkan if pernyataan dan juga bagian dalam for pernyataan. Itu membuat kode lebih rapi. Perhatikan keduanya B%15 seharusnya B%16 dan B%255 seharusnya B%256. - Dennis Williamson


Saya telah menemukan skrip ini "satu-liner" yang berguna di mana uuidgen tidak tersedia. Ini juga melewati setiap neccessity untuk menginstal modul eksternal untuk Perl atau Python.

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

Diuji pada SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 dan yang lebih baru berhasil. Saya ingin tahu apakah ini rentan terhadap keunikan, tetapi saya belum 'bit'ten dalam 10 tahun terakhir. Tentu saja, head -1 bisa diganti dengan head -_other-value_ | tail -1 terlalu.

Untuk menjelaskan,

/dev/random dan /dev/urandom adalah generator acak kernel.

od (oktal dump) memiliki saklar output hex (-x) menghasilkan 16 byte per baris.

head -n [| tail -1] (di mana n> 0) hanya mengekstrak satu baris dari output sebelumnya.

awk menetapkan OutputFieldSeparator menjadi tanda hubung di mana-mana koma terjadi dalam pernyataan cetak. Dengan menetapkan bidang 2-9 secara independen, kami mengontrol tanda hubung dan menghapus konter indeks / offset yang aw 'prefixes setiap baris output dengan.

Hasilnya adalah pola 8-4-4-4-12 karakter huruf kecil a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

13
2017-08-25 23:57



Cemerlang! hanya satu baris tanpa dependensi, BSD / macOS kompatibel ... hebat - dinigo
Melakukan TIDAK gunakan "ekor -1". Jika Anda hanya menjalankan "od-x / dev / urandom" dengan sendirinya, itu berlangsung tanpa batas, terus menghasilkan lebih banyak baris data acak. "ekor -1" mungkin hanya duduk di sana selamanya menunggu baris "terakhir". Kalau tidak, itu solusi yang bagus. - UncaAlby
Harap dicatat, ekor hanya dalam "penjelasan" sebagai parameter opsional ketika jumlah garis yang dikeluarkan oleh kepala lebih besar dari satu. Ada untuk memastikan menerima satu baris 16 byte oleh awk, dan bukan bagian dari perintah asli. Pipa untuk menuju dari od sudah membersihkan output untuk pemipaan ke ekor -1. Dalam pengalaman saya, satu-satunya ekor waktu menunggu selamanya adalah dengan argumen -f. Saya mohon maaf jika penjelasannya tidak jelas di mana menyatakan penggunaan ekor -1 hanya diperlukan ketika output dari kepala menghasilkan lebih dari satu baris. - dan
Melakukan tidak gunakan ini, itu benar-benar melanggar spesifikasi UUID. Hanya UUID versi 4 yang boleh acak seperti ini. - jlh
@ jlh Saya tidak yakin mengapa pertanyaan ini dikunci, tetapi inilah versi tetap yang membuat pendekatan ini UUID-v4 sesuai: 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


Hanya saja python tidak merasa ditinggalkan:

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

Untuk menggunakannya di shell:

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

Lihat Dokumentasi Python UUID untuk jenis UUID yang dapat dihasilkan.

Untuk menghasilkan file sistem-id yang kompatibel dengan sistem pada mesin non-sistem, Anda dapat menggunakan python untuk melakukannya dengan cara ini:

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

12
2018-01-16 15:26





Perl menyediakan pustaka UUID berdasarkan pada e2fsprogs paket. Pada sistem Debian saya itu libuuid-perl paket. Berikut ini contoh satu-liner; Lihat man uuid untuk lebih:

$ 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

Ini akan menjadi sepele untuk ditambahkan ke shellscript dengan backticks atau $() notasi:

#!/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 - Bantu saya banyak! - rafa.ferreira