Назад | Перейти на главную страницу

Как создать UUID в bash?

В Java можно создать случайный UUID:

UUID uuid = UUID.randomUUID();

Как это сделать в Баше?

Увидеть uuidgen программа, которая является частью e2fsprogs пакет.

В соответствии с этот, libuuid теперь является частью утилита-Linux и включение в e2fsprogs постепенно прекращается. Однако в новых системах Ubuntu uuidgen сейчас в uuid-runtime пакет.

Чтобы создать uuid и сохранить его в переменной:

uuid=$(uuidgen)

В моей системе Ubuntu альфа-символы выводятся в нижнем регистре, а в моей системе OS X они выводятся в верхнем регистре (спасибо Дэвиду за указание на это в комментарии).

Чтобы переключиться на верхний регистр (после генерации, как указано выше):

uuid=${uuid^^}

Чтобы переключиться на все строчные буквы:

uuid=${uuid,,}

Если, например, у вас есть два UUID, и вы хотите сравнить их в Bash, игнорируя их регистр, вы можете сделать tolower() сравнение стилей так:

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

Чтобы добавить разнообразия без добавления внешних зависимостей, на Linux ты можешь сделать:

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

Для распространения плохой практики на FreeBSD, под слоем совместимости с Linux (linuxulator?),

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

Ссылки:

Просто для полноты картины ... Там же установлен генератор UUID с dbus пакет на Debian. Я пропустил это, глядя вокруг раньше. Вероятно, это тот же алгоритм, что и пакет e2fsprogs, но он не добавляет дефисы, поэтому он может быть немного чище для вас:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity добавляет совет по безопасности: «UUID DBus не связаны и не совместимы с RFC 4122. Кроме, dbus-uuidgen всегда использует временную метку Unix как последние 4 байта. Так что они могут быть непригодными для некоторых целей ». (Спасибо, Гравити, я должен был заметить это на странице руководства.)

Если вы не хотите зависеть от других исполняемых файлов или не можете их использовать, вот чистая версия bash от Вот:

# 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

Я нашел этот сценарий "однострочным" полезным там, где uuidgen недоступен. Это также обходит любую необходимость установки внешних модулей для Perl или Python.

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 и новее. Мне любопытно, подвержено ли это неуникальности, но меня не «кусали» последние 10 лет. Конечно, head -1 можно заменить на head -_other-value_ | tail -1 слишком.

Объяснять,

/dev/random и /dev/urandom - генераторы случайных чисел ядра.

od (восьмеричный дамп) имеет шестнадцатеричный переключатель вывода (-x), выдающий 16 байт на строку.

head -n [| tail -1] (где n> 0) извлекает только одну строку из предыдущего вывода.

awk устанавливает для параметра OutputFieldSeparator дефис везде, где в операторе печати встречается запятая. Задавая поля 2-9 независимо, мы контролируем дефисы и удаляем счетчик индекса / смещения, которым 'od' ставится префикс каждой строки вывода.

В результате получился узор из 8-4-4-4-12 символы нижнего регистра a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

Просто чтобы питон не чувствовал себя обделенным:

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

Чтобы использовать его в оболочке:

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

Увидеть Документация Python UUID для типов UUIDS, которые могут быть созданы.

Чтобы сгенерировать файл, совместимый с systemd machine-id на машине, отличной от systemd, вы можете использовать python, чтобы сделать это следующим образом:

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

Perl предоставляет библиотеку UUID на основе e2fsprogs пакет. В моей системе Debian это 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

Это было бы тривиально добавить в сценарий оболочки с помощью обратных кавычек или $() обозначение:

#!/bin/bash
# ...do some stuff
$myvar = $(perl -e 'use UUID;  UUID::generate($uuid);  UUID::unparse($uuid, $string);  print "$string";')
# ...do some more stuff
apt-get install uuid

Работал на меня, потом я сбежал uuid

Я написал небольшую функцию 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"')]))'

Пожалуйста, посмотрите библиотеку OSSP UUID (http://www.ossp.org/pkg/lib/uuid/) и подумайте об установке. Некоторые проекты предлагают это в качестве опции (например, PostgreSQL). Он правильно обрабатывает UUID версий 3 и 5., что выходило за рамки того, с чем могла справиться моя установленная (например, e2fsprogs) библиотека. К счастью, у openSUSE он есть в одном из основных репозиториев. Получить версию для работы с Windows (например, Cygwin) или MySQL было нелегко. Похоже, пора перейти на Linux / PostgreSQL / Python (и мне так понравился графический интерфейс SQLyog для MySQL / MariaDB), поскольку мне действительно нужны UUID v3 и v5.

Я уверен, что некоторые из них прибудут сюда и просто ищут простой способ сгенерировать уникальный идентификатор для использования в своих сценариях, и это не обязательно должен быть настоящий UUID.

Если это так, вы можете просто сделать следующее, что сгенерирует идентификатор, уникальный с точностью до секунды, поэтому, если вы запустите это несколько раз в течение секунды, вы все равно получите тот же результат.

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

будет генерировать идентификаторы, подобные приведенным ниже, на основе текущего системного времени:

U1454423662

ПРИМЕЧАНИЕ. Если вы работаете в Linux или у вас установлен Coreutils на Mac, вы можете использовать следующее для создания уникального идентификатора с точностью до наносекунды:

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

или если вы предпочитаете решение на основе Python с точностью до наносекунды, которое должно работать почти везде, запустите:

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

Эта ветка с разнообразными примерами была мне очень полезна. Мне часто нужны функции uuid из разных сред. И хотя мне нравятся примеры на чистом bash, иногда удобнее использовать библиотеку с другого языка.

Так что для полноты картины в ruby ​​(1.9.3+) есть встроенный модуль SecureRandom, содержащий ряд полезных функций хеширования и идентификатора. Это можно сделать с помощью bash cli.

ruby -r securerandom -e 'puts SecureRandom.uuid'
ran=`od -X -A n /dev/random | head -1 | cut -c3-38`

correlation_id=`echo ${ran} | cut -c1-8`-`echo ${ran} | cut -c10-13`-`echo ${ran} | cut -c14-17`-`echo ${ran} | cut -c19-22`-`echo ${ran} | cut -c23-26``echo ${ran} | cut -c28-35`

Если вы используете Java 10.

$ jshell
jshell> import java.util.*
jshell> String id = UUID.randomUUID().toString();