如何在 bash 中创建 UUID?

rao*_*son 185 bash uuid

在 Java 中,可以创建一个随机UUID

UUID uuid = UUID.randomUUID();
Run Code Online (Sandbox Code Playgroud)

如何在 Bash 中做到这一点?

Den*_*son 224

请参阅作为e2fsprogsuuidgen一部分的程序。

根据这个libuuid现在是一部分的util-linux的并且包含在e2fsprogs的将被淘汰。但是,在新的 Ubuntu 系统上,uuidgen现在已包含在uuid-runtime软件包中。

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

uuid=$(uuidgen)
Run Code Online (Sandbox Code Playgroud)

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

切换到所有大写(如上生成后):

uuid=${uuid^^}
Run Code Online (Sandbox Code Playgroud)

要切换到所有小写:

uuid=${uuid,,}
Run Code Online (Sandbox Code Playgroud)

例如,如果您有两个 UUID,并且您想在 Bash 中比较它们,忽略它们的大小写,您可以tolower()进行如下样式比较:

if [[ ${uuid1,,} == ${uuid2,,} ]]
Run Code Online (Sandbox Code Playgroud)

  • 嘿,不公平!我的 e2fsprogs 没有附带那个!我想要一个,哪里可以买到?(更新:啊哈... debian 无缘无故地将它放在 `uuid-runtime` 包中...+1 给你) (7认同)
  • 我注意到 Mac 上的 uuidgen 全大写,而 Ubuntu(来自 util-linux 2.20.1 的 uuidgen)全小写。为什么会有差异?Ubuntu 还列出了该工具的来源,但在 Mac 上,没有版本信息,也没有它来自哪个软件包。 (2认同)

Sam*_*een 167

要在不添加外部依赖项的情况下添加多样性,在Linux 上您可以执行以下操作:

UUID=$(cat /proc/sys/kernel/random/uuid)
Run Code Online (Sandbox Code Playgroud)

传播不良做法,在FreeBSD 上,在 linux 兼容层(linuxulator?)下,

UUID=$(cat /compat/linux/proc/sys/kernel/random/uuid)
Run Code Online (Sandbox Code Playgroud)

参考:

  • 这太棒了。 (19认同)
  • 对于真正最小的设置,如 Docker 容器,这是一个更好的答案。 (6认同)
  • 这应该避免,因为它是高度不可移植的(尽管 FreeBSD 为写得不好的应用程序提供 /compat/linux/proc/sys/kernel/random/uuid) (3认同)
  • 这应该是最好的答案! (2认同)

qua*_*ote 34

只是为了完整性......还有一个 UUID 生成器安装dbus在 Debian 上的软件包中。我错过了早些时候环顾四周。它可能与 e2fsprogs 包的算法相同,但它没有添加破折号,所以它可能对你来说更清晰一些:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6
Run Code Online (Sandbox Code Playgroud)

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

  • DBus UUID 与 RFC 4122 无关或不兼容。此外,`dbus-uuidgen` 始终使用 Unix 时间戳作为最后 4 个字节。所以它们可能不适合某些用途。 (7认同)

小智 20

如果你不希望依赖于其他可执行文件,也可以不使用它们,这里是从纯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
Run Code Online (Sandbox Code Playgroud)


dan*_*dan 19

我发现这个脚本“单行”在 uuidgen 不可用的情况下很有用。这也绕过了为 Perl 或 Python 安装外部模块的任何必要性。

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

在 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
Run Code Online (Sandbox Code Playgroud)

  • @jlh 我不确定为什么这个问题被锁定,但这里有一个固定版本,使这种方法符合 UUID-v4:`od -x /dev/urandom | 头-1 | awk '{OFS="-"; srand($6); sub(/./,"4",$5); sub(/./,substr("89ab",rand()*4,1),$6); 打印 $2$3,$4,$5,$6,$7$8$9}'` (3认同)
  • 不要**不要**使用它,它完全违反了 UUID 规范。仅允许版本 4 UUID 像这样是随机的。 (2认同)

dav*_*vey 14

只是为了让 python 不会被排除在外:

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

要在 shell 中使用它:

myvar=$(python  -c 'import uuid; print uuid.uuid1()')
Run Code Online (Sandbox Code Playgroud)

有关可以生成的UUID类型,请参阅Python 文档 UUID

要在非 systemd 机器上生成 systemd machine-id 兼容文件,您可以使用 python 来这样做:

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


qua*_*ote 11

Perl 提供了一个基于e2fsprogs包的 UUID 库。在我的 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
Run Code Online (Sandbox Code Playgroud)

用反引号或$()符号添加到 shellscript 是微不足道的:

#!/bin/bash
# ...do some stuff
$myvar = $(perl -e 'use UUID;  UUID::generate($uuid);  UUID::unparse($uuid, $string);  print "$string";')
# ...do some more stuff
Run Code Online (Sandbox Code Playgroud)