题 如何在bash中创建UUID?


在Java中,可以创建随机的 UUID

UUID uuid = UUID.randomUUID();

如何在Bash中执行此操作?


163
2018-01-16 13:41






答案:


uuidgen 该计划是该计划的一部分 的e2fsprogs 包。

根据 这个libuuid 现在是其中的一部分 UTIL Linux的 并且e2fsprogs中的包含正在逐步淘汰。但是,在新的Ubuntu系统上, uuidgen 现在在 uuid-runtime 包。

要创建一个uuid并将其保存在变量中:

uuid=$(uuidgen)

在我的Ubuntu系统上,字母字符输出为小写,在我的OS X系统上,它们以大写形式输出(感谢David在评论中指出这一点)。

要切换到全部大写(在如上生成之后):

uuid=${uuid^^}

要切换到全部小写:

uuid=${uuid,,}

例如,如果你有两个UUID并且你想在Bash中比较它们,忽略它们的情况,你可以做一个 tolower() 风格比较如下:

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

185
2018-01-16 14:01



嘿,不公平!我的e2fsprogs没有附带!我想要一个,我从哪里得到它? (更新:啊...... debian把它粘在了 uuid-runtime 包装没有明显的理由...给你+1) - quack quixote
uuidgen来自freeBSD。它并不总是在e2fsprogs包中。 - Good Person
@Rob:回答你原来的问题,这是为了 驱动标签。 - Dennis Williamson
我注意到Mac上的uuidgen全部大写,而Ubuntu(来自util-linux 2.20.1的uuidgen)全部以小写形式发出。为什么不同?此外,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)

参考文献:


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的UUID发生器 dbus 在Debian上打包。我错过了早些时候环顾四周。它可能与e2fsprogs包的算法相同,但它不会添加破折号,因此它可能会更清洁:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity添加了一个安全提示:“DBus UUID与之无关或兼容 RFC 4122。除了, DBUS-的uuidgen 始终使用Unix时间戳作为最后4个字节。所以它们可能不适合某些用途。“(谢谢,Grawity,我应该在联机帮助页中发现它。)


28
2018-01-16 14:18



DBus 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


我发现这个脚本“one-liner”在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设置为在print语句中出现逗号的地方的连字符。通过独立指定字段2-9,我们控制连字符并剥离索引/偏移计数器,其中'od'为每行输出添加前缀。

结果是一种模式 8-4-4-4-12 小写字符 a-f0-9

993bb8d7-323d-b5ee-db78-f976a59d8284

13
2017-08-25 23:57



辉煌!只有一行没有依赖,BSD / macOS兼容......很棒 - dinigo
做 不 使用“尾巴-1”。如果你自己只运行“od -x / dev / urandom”,它会无限期地继续产生更多的随机数据。 “尾巴-1”可能只是坐在那里等待“最后”线。否则,这是一个很好的解决方案。 - UncaAlby
请注意,当head输出的行数大于1时,tail仅作为可选参数的“说明”。确保通过awk接收单行16字节,并且不是原始命令的一部分。来自od的管道已经消毒了管道输出到尾部-1。根据我的经验,tail永远等待的唯一时间是使用-f参数。我很抱歉,如果解释不明确,那么只有当head的输出产生多于一行时才需要使用tail -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不会感到被遗忘:

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

要在shell中使用它:

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

Python文档UUID 对于可以生成的各种UUIDS。

要在非系统机器上生成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

用反引号或者添加到shellcript中这将是微不足道的 $() 符号:

#!/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





我用Python编写了一个小的Bash函数来批量生成任意数量的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 UUID,这超出了我安装的(例如e2fsprogs)库可以处理的范围。幸运的是,openSUSE将其置于其中一个主要的回购中。使用Windows(例如Cygwin)或MySQL工作的版本已经成为一个连枷。看起来是时候切换到Linux / PostgreSQL / Python(我非常喜欢SQLyog GUI到MySQL / MariaDB),因为我真的需要v3和v5 UUID。


1
2017-09-23 23:37



完全同意!对于我的用例,它是完美的,因为它也支持命名空间 -v3 ns:URL custom-data 播种机制。 - Roberto Andrade