Вопрос: Как создать UUID в bash?


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

UUID uuid = UUID.randomUUID();

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


161
2018-01-16 13:41


Источник




Ответы:


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

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

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

uuid=$(uuidgen)

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

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

uuid=${uuid^^}

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

uuid=${uuid,,}

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

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

178
2018-01-16 14:01



эй, честно! мой e2fsprogs не пришел с этим! Я хочу один, где я его получу? (обновление: ahhh ... debian вставляет его в uuid-runtime пакет без видимых причин ... +1 к вам) - quack quixote
uuidgen входит в состав freeBSD. он не всегда находится в пакете e2fsprogs. - Good Person
@Rob: Чтобы ответить на ваш первоначальный вопрос, это для этикетки для дисков, - Dennis Williamson
Я замечаю, что uuidgen на Mac испускает все прописные буквы, а Ubuntu (uuidgen from 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


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

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

Чтобы пропагандировать плохие практики, FreeBSD, под уровнем совместимости linux (linuxulator?),

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

Рекомендации:


124
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 пакет на Debian. Я пропустил это, оглядываясь раньше. Вероятно, это тот же алгоритм, что и пакет e2fsprogs, но он не добавляет тире, поэтому он может быть немного чище для вас:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

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


27
2018-01-16 14:18



DBU UUID не связаны или не совместимы с RFC 4122. Кроме того, dbus-uuidgenвсегда использует временную метку Unix в качестве последних 4 байтов. Поэтому они могут быть непригодны для некоторых целей. - grawity
такие же работы на Fedora-25 тоже ... - kmonsoor


Если вы не хотите зависеть от других исполняемых файлов, или вы не можете их использовать, вот чистая версия 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

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 недоступен. Это также исключает необходимость установки внешних модулей для 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

13
2017-08-25 23:57



Brilliant! просто одна строка без каких-либо зависимостей, совместимость с BSD / macOS ... отлично - dinigo
Делать НЕ используйте «tail -1». Если вы запускаете только «od -x / dev / urandom» самостоятельно, он работает бесконечно, непрерывно производя больше строк случайных данных. «tail -1» может просто сидеть там навсегда, ожидая «последней» линии. В противном случае это хорошее решение. - UncaAlby
Обратите внимание, что хвост находится только в «объяснении» в качестве необязательного параметра, когда количество строк, выводимых головкой, больше единицы. Там, чтобы обеспечить получение одной строки из 16 байтов awk и не является частью исходной команды. Труба на головку от od уже санирует выход для трубопровода до хвоста -1. По моему опыту, единственный хвост, который всегда ждет, с аргументом -f. Приносим извинения, если объяснение неясно, где указано, что использование хвоста -1 необходимо только тогда, когда вывод головки создает более одной строки. - dan
Делать не используйте это, он полностью нарушает спецификацию UUID. Только UUID версии 4 допускается быть случайным, как это. - jlh


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

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

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

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

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

Чтобы сгенерировать файл systemdd, совместимый с машиной, на машине, отличной от systemd, вы могли бы использовать python для этого:

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

12
2018-01-16 15:26





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

Это было бы тривиально, чтобы добавить к 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

Работал для меня, затем id бежал 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





Пожалуйста, просмотрите библиотеку UUID OSSP (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.


1
2017-09-23 23:37



Согласитесь полностью! Для моего варианта использования он был идеальным, так как он также поддерживает -v3 ns:URL custom-data механизм посева. - Roberto Andrade