سؤال كيفية إنشاء UUID في باش؟


في Java ، من الممكن إنشاء عشوائي UUID:

UUID uuid = UUID.randomUUID();

كيف تفعل هذا في باش؟


163
2018-01-16 13:41


الأصل




الأجوبة:


شاهد uuidgen البرنامج الذي هو جزء من e2fsprogs صفقة.

بالنسبة الى هذه، libuuid هو الآن جزء من UTIL لينكس ويتم التخلص من إدراج في e2fsprogs بها. ومع ذلك ، على أنظمة Ubuntu الجديدة ، uuidgen هو الآن في uuid-runtime صفقة.

لإنشاء uuid وحفظه في متغير:

uuid=$(uuidgen)

على نظام Ubuntu الخاص بي ، يتم إنتاج أحرف alpha كحرف صغيرة وعلى نظام OS X الخاص بي ، يتم إخراجها كحالة كبيرة (بفضل David للإشارة إلى ذلك في تعليق).

للتبديل إلى الحالة العلوية (بعد توليدها على النحو الوارد أعلاه):

uuid=${uuid^^}

للتبديل إلى جميع الحالات الصغيرة:

uuid=${uuid,,}

إذا ، على سبيل المثال ، لديك UUIDs وتريد مقارنتها في Bash ، تجاهل حالتها ، يمكنك القيام tolower() مقارنة نمط مثل هذا:

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

186
2018-01-16 14:01



مهلا ، لا عادلة! بلدي e2fsprogs لم يأت مع ذلك! اريد واحد ، من أين يمكنني الحصول عليه؟ (التحديث: ahhh ... ديبيان العصي في uuid-runtime حزمة بدون سبب واضح ... +1 لك) - quack quixote
يأتي uuidgen مدمج على فري. انها ليست دائما في حزمة e2fsprogs. - Good Person
Rob: للإجابة على سؤالك الأصلي ، من أجل تسميات محرك الأقراص. - Dennis Williamson
ألاحظ uuidgen على ماك تنبعث في جميع الأحرف الكبيرة أثناء Ubuntu (uuidgen من util-linux 2.20.1) في جميع الأحرف الصغيرة. لماذا الفرق؟ كما تم إدراج Ubuntu أيضًا في المكان الذي تأتي منه الأداة ولكن على Mac ، وليس هناك معلومات عن الإصدار ولا الحزمة التي وردت منها. - David
David: أعتقد أنه جزء من نظام التشغيل الأساسي على نظام التشغيل OS X. ليس لدي أي فكرة عن السبب في كون الحالة العليا والأخرى أقل. لا يهم حقا لأن إما تمثل أحرف سداسي عشري صالحة (echo -e 'f\nF' | grep '[[:xdigit:]]' إخراج كل من الخطوط). إذا كان ذلك مهمًا بالنسبة لك ولديك Bash 4 ، فيمكنك القيام بذلك لجعله أقل حالة: uuid=$(uuidgen); uuid=${uuid,,}أو هذا لجعلها الحالة العليا: uuid=$(uuidgen); uuid=${uuid^^} أو شيء من هذا القبيل للقيام بذلك tolower() اختبار النمط: if [[ ${uuid1,,} == ${uuid2,,} ]] - Dennis Williamson


لإضافة مجموعة بدون إضافة تبعيات خارجية ، في لينكس يمكنك ان تفعل:

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

لنشر الممارسات السيئة ، على فري، تحت طبقة توافق linux (linuxulator؟) ،

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

المراجع:


128
2017-08-07 12:55



هذا رائع. - Tom O'Connor
يجب تجنب هذا لأنه غير قابل للنقل بشكل كبير (على الرغم من مستلزمات FreeBSD / compat / linux / proc / sys / kernel / random / uuid للتطبيقات المكتوبة بشكل سيء) - Good Person
تناسبها تماما للاستخدام داخل صورة initrd - Maximilian
لا تظهر طريقة FreeBSD على نظام التشغيل Mac OS X (أو طريقة Linux). يبدو uuidgen على الأقل مثبتًا مسبقًا على جهاز Mac (أو تم تثبيته بشيء آخر قمت بتثبيته). - David
هذه إجابة أفضل للإعدادات البسيطة ، مثل حاوية Docker. - jacderida


فقط من أجل اكتمالها ... وهناك أيضا مولد UUID المثبتة مع dbus حزمة على دبيان. فاتني أن ننظر حولها في وقت سابق. من المحتمل أنها نفس الخوارزمية مثل حزمة e2fsprogs ، ولكنها لا تضيف الشرطات ، لذا قد يكون منظفًا صغيرًا لك:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

تضيف Grawity نصيحة أمان: "لا يرتبط UUIDs لـ DBus أو متوافق مع RFC 4122. الى جانب ذلك، DBus تثبيت-uuidgen يستخدم دائمًا الطابع الزمني لـ Unix ليكون آخر 4 بايت. لذلك قد يكونون غير مناسبين لبعض الاستخدامات. "(شكرًا ، Grawity ، كان يجب أن ألاحظ ذلك في الصفحة الرئيسية).


28
2018-01-16 14:18



لا ترتبط UUIDs لـ DBus أو تتوافق مع RFC 4122. بالإضافة إلى ذلك ، dbus-uuidgen يستخدم دائمًا الطابع الزمني لـ Unix ليكون آخر 4 بايت. لذلك قد تكون غير مناسبة لبعض الاستخدامات. - grawity
نفس العمل على فيدورا -25 ، أيضا ... - kmonsoor


إذا كنت لا ترغب في الاعتماد على الملفات التنفيذية الأخرى ، أو لا يمكنك استخدامها ، فإليك إصدار bash pure من هنا:

# 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 يمكن القضاء على متغير و for T حلقة يمكن تغييرها إلى: case $N in 3 | 5 | 7 | 9) printf '-';; esac (موزعة على خطوط منفصلة إذا فضلت). - Dennis Williamson
لقد أضفت تعليقًا على الشفرة في رابط github الذي يعرض إصدارًا باستخدام case للقضاء على if البيانات وكذلك الداخلية for بيان. يجعل الرمز أكثر إتقانا. لاحظ أن كليهما B%15 يجب ان يكون B%16 و B%255 يجب ان يكون B%256. - Dennis Williamson


لقد وجدت هذا البرنامج النصي "واحد بطانة" مفيدة حيث uuidgen غير متوفر. هذا أيضا يتجاوز أي neccessity لتثبيت وحدات خارجية لبيرل أو بايثون.

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

اختبارها على SnowLeopard ، ريد هات فالهالا ، سولاريس 9 4/04 وأحدث بنجاح. أنا أشعر بالفضول إذا كان هذا عرضة لعدم التفرد ، ولكني لم أكن قد التقطت في السنوات العشر الماضية. بالطبع بكل تأكيد، head -1 يمكن الاستعاضة عنها head -_other-value_ | tail -1 جدا.

لشرح،

/dev/random و /dev/urandom هي مولدات عشوائية kernel.

od (تفريغ الثماني) لديه مفتاح إخراج عرافة (-x) إنتاج 16 بايت لكل سطر.

head -n [| الذيل -1] (حيث N> 0) يستخرج سطر واحد فقط من الناتج السابق.

awk تعيين OutputFieldSeparator ليكون واصلة في كل مكان تحدث فاصلة في عبارة الطباعة. من خلال تحديد الحقول 2-9 بشكل مستقل ، نتحكم في الواصلات ونقطع الشرائط عن عداد الفهرسة / الإزاحة التي تقوم بادئة "od" بادخال كل سطر منها.

والنتيجة هي نمط من 8-4-4-4-12 أحرف صغيرة a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

14
2017-08-25 23:57



متألق! مجرد خط واحد مع عدم وجود تبعيات ، BSD / macOS متوافق ... عظيم - dinigo
فعل ليس استخدم "tail -1". إذا قمت بتشغيل فقط "od -x / dev / urandom" في حد ذاته ، فإنه يستمر لفترة غير محددة ، باستمرار إنتاج المزيد من خطوط البيانات العشوائية. "الذيل -1" قد يجلس هناك إلى الأبد بانتظار الخط "الأخير". خلاف ذلك ، إنه حل جيد. - UncaAlby
يرجى ملاحظة أن الذيل موجود فقط في "الشرح" كمعلمة اختيارية عندما يكون عدد الأسطر الناتج من الرأس أكبر من واحد. هناك لضمان تلقي خط واحد من 16 بايت من قبل awk ، وليس جزءا من القيادة الأصلية. الأنبوب لرأس من od بالفعل يعقم الإخراج ل piping إلى الذيل -1. من واقع خبرتي ، فإن الذيل الزمني الوحيد الذي ينتظر إلى الأبد يكون بحجة -f. أعتذر إذا كان التفسير غير واضح حيث يشير إلى أن استخدام الذيل -1 ضروري فقط عندما ينتج خرج الرأس أكثر من سطر واحد. - dan
فعل ليس استخدام هذا ، فإنه ينتهك تماما مواصفات UUID. يتم السماح فقط الإصدار 4 UUID عشوائي مثل هذا. - jlh
jlh لست متأكدًا من سبب قفل هذا السؤال ، ولكن إليك إصدار ثابت يجعل هذا الأسلوب متوافق مع 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


فقط لا يبدو أن بايثون مُستبعدة:

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

لاستخدامها في وعاء:

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

شاهد بيثون التوثيق UUID لأنواع UUIDS التي يمكن توليدها.

لإنشاء ملف متوافق مع جهاز systemd id على جهاز غير systemd ، يمكنك استخدام python للقيام بذلك بهذه الطريقة:

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

12
2018-01-16 15:26





بيرل يوفر مكتبة UUID على أساس e2fsprogs صفقة. على نظام ديبيان الخاص بي هو libuuid-perl صفقة. وهنا مثال على واحد الخطوط الملاحية المنتظمة ؛ نرى man uuid للمزيد من:

$ 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

هذا من شأنه أن يكون تافها لإضافة إلى shellscript مع backticks أو $() الرموز:

#!/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 - ساعدني كثيرا! - rafa.ferreira


apt-get install uuid

عملت لي ، ثم تشغيل معرف uuid


3
2018-06-19 09:07





كتبت دالة Bash صغيرة باستخدام Python لتوليد عدد تعسفي من UUID بشكل جماعي:

# 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"')]))'
}

إذا كنت تفضل الأحرف الصغيرة ، فقم بالتغيير:

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
2017-08-03 22:16





يرجى إلقاء نظرة على مكتبة OSSP UUID (http://www.ossp.org/pkg/lib/uuid/) ، والنظر في تثبيته. بعض المشاريع تقدمه كخيار (على سبيل المثال PostgreSQL). يعالج بشكل صحيح الإصدار 3 و الإصدار 5 UUIDs، والتي تجاوزت ما يمكن لمكتبتي المثبتة (مثل e2fsprogs) التعامل معه. لحسن الحظ ، فقد openSUSE في واحدة من repos الرئيسية. الحصول على نسخة للعمل مع ويندوز / (على سبيل المثال Cygwin) أو MySQL قد تم flail. يبدو أنه حان الوقت للتبديل إلى Linux / PostgreSQL / Python (وأنا حتى أحب واجهة المستخدم الرسومية SQLyog إلى MySQL / MariaDB) لأنني حقا بحاجة إلى V3 و V5 UUID.


1
2017-09-23 23:37



أتفق تماما! بالنسبة لحالتي التي استخدمتها ، كانت مثالية لأنها تدعم أيضًا نقل الأسماء عبر -v3 ns:URL custom-data آلية البذر. - Roberto Andrade


أنا متأكد من أن البعض سيصل إلى هنا ، وهم يبحثون عن طريقة سهلة لإنشاء معرّف فريد لاستخدامه في نصوصهم البرمجية ، ولا يلزم أن يكون UUID صحيحًا.

إذا كان الأمر كذلك ، فيمكنك القيام بما يلي فقط ، مما سيؤدي إلى إنشاء معرف فريد إلى الثاني - لذلك إذا قمت بتشغيل هذا عدة مرات خلال ثانية ، فستستمر في الحصول على نفس النتيجة.

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

سوف يقوم بإنشاء معرفات مثل التالية استنادًا إلى وقت النظام الحالي:

U1454423662

ملاحظة: إذا كنت تستخدم Linux ، أو إذا كانت Coreutils مثبتة على جهاز ماكنتوش ، فيمكنك استخدام ما يلي لإنشاء معرف فريد إلى nanosecond:

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

أو إذا كنت تفضل حل يستند إلى python إلى nanosecond ، والذي يجب أن يعمل في كل مكان تقريباً ، قم بتشغيل:

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

1
2018-02-02 14:38



هذا هو عموما ممارسة سيئة للغاية. أجهزة الكمبيوتر الحديثة قادرة على تشغيل العديد من الأشياء بشكل متوازٍ وإكمال المهام التسلسلية بسرعة ، ولكن هذا المعرف سيكون متطابقًا مع أي استدعاءات في غضون ثانية واحدة. ناهيك عن أي أجهزة كمبيوتر أخرى تقوم بتشغيل هذا البرنامج النصي في نفس الوقت. خيار أفضل ولكن لا يزال ليس كبيرا mktemp -u كما في MYID="$(mktemp -u)". إذا كنت تستطيع تحمل ملفات مؤقتة فارغة حول تمهيد حتى إعادة التشغيل ، إفلات -u: MYID="$(mktemp)" - Chris Harrington
مهلا ... نقاط جيدة على فريدة فقط إلى النقطة الثانية ... سأضيف بعض الملاحظات أعلاه ... - Brad Parks