Soru Bash içinde UUID nasıl oluşturulur?


Java'da rastgele oluşturulabilir. UUID:

UUID uuid = UUID.randomUUID();

Bash'de bunu nasıl yapabilirim?


163
2018-01-16 13:41


Menşei




Cevaplar:


Bakın uuidgen programının bir parçası e2fsprogs paketi.

Göre bu, libuuid şimdi bir parçası util-linux ve e2fsprogs'a eklenmesi aşamalı olarak kaldırılıyor. Ancak, yeni Ubuntu sistemlerinde, uuidgen şimdi içinde uuid-runtime paketi.

Uuid oluşturmak ve değişkene kaydetmek için:

uuid=$(uuidgen)

Ubuntu sistemimde, alfa karakterleri küçük harf olarak ve OS X sistemimde çıktı olarak verilir, bunlar büyük harf olarak verilir (bir yorumda bunu belirtmek için David'e teşekkürler).

Tüm büyük harflere geçmek için (yukarıdaki gibi oluşturulduktan sonra):

uuid=${uuid^^}

Tüm küçük harflere geçmek için:

uuid=${uuid,,}

Örneğin, iki UUID'iniz varsa ve bunları Bash'de karşılaştırmak istiyorsanız, durumlarını göz ardı ederek tolower() stil karşılaştırma şöyle:

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

186
2018-01-16 14:01



hey, adil değil! e2fsprogs'm bununla gelmedi! Ben istiyorum, nereden alabilirim? (güncelleme: ahhh ... debian bunu sopalarla uuid-runtime Belirsiz bir sebep için paket ... +1) - quack quixote
uuidgen, freeBSD'de yerleşik olarak gelir. e2fsprogs paketinde her zaman değil. - Good Person
@Rob: Asıl sorunuzu yanıtlamak için sürücü etiketleri. - Dennis Williamson
Mac’deki uuidgen’in, tüm küçük harflerde Ubuntu’da (util-linux 2.20.1’den uuidgen) tüm büyük harfleri yayar. Neden farkı? Ayrıca Ubuntu, aracın Mac'ten geldiği yerde listelendi, sürüm bilgisi veya hangi paketten geldiğini bilmiyoruz. - David
@David: OS X'deki temel işletim sisteminin bir parçası olduğuna inanıyorum. Birinin neden büyük ve diğerinin daha düşük olduğu konusunda hiçbir fikrim yok. Geçerli altıgen karakterleri temsil ettiği için gerçekten önemli değildir (echo -e 'f\nF' | grep '[[:xdigit:]]' her iki satırı da gönderir). Sizin için önemli olan ve Bash 4'ünüz varsa, bunu küçük harf yapmak için yapabilirsiniz: uuid=$(uuidgen); uuid=${uuid,,} veya bunu büyük harfle yapmak için: uuid=$(uuidgen); uuid=${uuid^^} ya da bu çizgiler boyunca bir şeyler yapmak tolower() stil testi: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


Dış bağımlılıklar eklemeden çeşitlilik eklemek için Linux yapabilirsin:

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

Kötü uygulamaları yaymak FreeBSDlinux uyumluluk katmanı altında (linuxulator?),

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

Referanslar:


128
2017-08-07 12:55



Bu harika. - Tom O'Connor
Son derece portatif olmadığı için bu durumdan kaçınılmalıdır (her ne kadar FreeBSD kaynakları / uyumlu / linux / proc / sys / kernel / zayıf yazılmış uygulamalar için rasgele / uuid olsa da) - Good Person
İnitrd görüntü içinde kullanım için mükemmel uyuyor - Maximilian
FreeBSD yöntemi Mac OS X'de (Linux metodu) görünmüyor. En azından uuidgen Mac'te önceden yüklenmiş olarak görünüyor (veya yüklediğim başka bir şeyle yüklenmiş). - David
Bu bir Docker kabı gibi asgari kurulumlar için daha iyi bir yanıttır. - jacderida


Sadece bütünlük adına ... Ayrıca bir UUID jeneratörü var. dbus Debian paketi. Daha önce etrafa bakmayı özledim. Muhtemelen e2fsprogs paketi ile aynı algoritmadır, ancak tire eklemez, bu yüzden sizin için biraz daha temiz olabilir:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity, bir güvenlik ipucu ekler: "DBus UUID'ler, bunlarla ilgili veya bunlarla uyumlu değil RFC 4122. Dışında, dbus-uuidgen her zaman Unix zaman damgasını son 4 bayt olarak kullanır. Bazı kullanımlar için uygun olmayabilirler. ”(Teşekkürler, Grawity, bunu manpage'de görmeliydim.)


28
2018-01-16 14:18



DBus UUID'ler RFC 4122 ile ilgili değildir veya bunlarla uyumlu değildir. dbus-uuidgen her zaman Unix zaman damgasını son 4 bayt olarak kullanır. Bu yüzden bazı kullanımlar için uygun olmayabilirler. - grawity
Aynı Fedora-25'de de çalışıyor ... - kmonsoor


Diğer çalıştırılabilirlere bağımlı olmak istemiyorsanız veya bunları kullanamıyorsanız, buradan saf bash sürümü İşte:

# 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



T değişken ortadan kaldırılabilir ve for T döngü şu şekilde değiştirilebilir: case $N in 3 | 5 | 7 | 9) printf '-';; esac (tercih edilirse ayrı hatlarda kırılmış). - Dennis Williamson
Kullanarak bir sürümü gösteren github bağlantısında bir kod ekledim case ortadan kaldırmak if ifadeler yanı sıra iç for Beyan. Kodu çok daha iyi hale getirir. İkisini de unutmayın B%15 olmalı B%16 ve B%255 olmalı B%256. - Dennis Williamson


Uuidgen'in mevcut olmadığı bu senaryoyu "tek liner" yararlı buldum. Bu ayrıca Perl veya Python için harici modüller yüklemek için herhangi bir gereksinimi atlar.

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

SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 ve daha yeni testler yapıldı. Bunun tekliksizliğe eğilimli olup olmadığını merak ediyorum, ama son 10 yılda 'bit'ten' değilim. Tabii ki, head -1 ile değiştirilebilir head -_other-value_ | tail -1 çok.

Açıklamak,

/dev/random ve /dev/urandom çekirdek rasgele jeneratörlerdir.

od (sekizli döküm), satır başına 16 bayt üreten bir hex çıkış anahtarına (-x) sahiptir.

head -n [| kuyruk -1] (n> 0), önceki çıktının sadece bir satırını çıkarır.

awk OutputFieldSeparator öğesini, yazdırma ifadesinde virgülün bulunduğu her yerde bir tire olacak şekilde ayarlar. 2-9 arasındaki alanları bağımsız olarak belirterek, tire işaretlerini kontrol eder ve indeks / ofset sayacını çıkarırız.

Sonuç bir desen 8-4-4-4-12 küçük harfli karakterler a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

14
2017-08-25 23:57



Parlak! bağımlılığı olmayan tek bir satır, BSD / macOS uyumlu ... harika - dinigo
Yap DEĞİL "kuyruk -1" kullanın. Sadece "od -x / dev / urandom" u çalıştırırsanız, sürekli olarak devam eder, sürekli olarak daha fazla rastgele veri satırı üretir. "kuyruk -1" sadece sonsuza kadar "son" çizgiyi bekleyerek orada oturabilir. Aksi takdirde, bu iyi bir çözüm. - UncaAlby
Lütfen dikkat, kuyruk, başlığa göre çıkış sayısı bir kereden fazla olduğunda, isteğe bağlı bir parametre olarak sadece "açıklama" durumundadır. Orada awk tarafından tek bir satır 16 bayt alma sağlamak için ve orijinal komutun bir parçası değildir. Odun başına giden boru, boru tesisatı çıkışını -1 kuyruğuna getirmektedir. Benim tecrübemde, sonsuza dek beklediği tek zaman kuyruğu, bir -f argümanı ile. Açıklama, kuyruk -1 kullanımının sadece başın çıkışı birden fazla çizgi oluşturduğunda belirtildiği yerde net olmadığı takdirde özür dilerim. - dan
Yap değil Bunu kullanın, UUID belirtimini tamamen ihlal eder. Sadece 4 UUID sürümünün böyle rastgele olmasına izin verilir. - jlh
Bu soru niçin kilitlendiğinden emin değilim, fakat bu yaklaşımın UUID-v4 uyumlu olmasını sağlayan sabit bir sürüm: 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


Sadece python kendini dışlanmış hissetmiyor:

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

Kabukta kullanmak için:

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

Bakın Python Belgeleri UUID Üretilebilecek UUIDS çeşitleri için.

Sistem dışı bir makinede bir makine kimliği makine kimliği uyumlu dosya oluşturmak için, python'u bu şekilde yapmak için kullanabilirsiniz:

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

12
2018-01-16 15:26





Perl, bir UUID kütüphanesi e2fsprogs paketi. Debian sistemimde libuuid-perl paketi. İşte bir örnek tek liner; görmek man uuid daha fazlası için:

$ 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

Bu backticks ile bir shellscript eklemek için önemsiz veya $() notasyonu:

#!/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 - Bana çok yardımcı olun! - rafa.ferreira