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

UUID uuid = UUID.randomUUID();


如何在Bash中执行此操作?

#1 楼

请参阅e2fsprogs软件包中的uuidgen程序。

据此,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,,} ]]


评论


嘿,不公平!我的e2fsprogs没有附带!我想要一个,我从哪里得到? (更新:ahhh ... debian毫无理由地将其粘贴在uuid-runtime程序包中... +1给您)

–嘎嘎吉qua德
2010年1月16日14:05



uuidgen内置在freeBSD中。它并不总是在e2fsprogs软件包中。

–好人
2014年5月22日在1:58

@Rob:要回答您的原始问题,它用于驱动器标签。

–丹尼斯·威廉姆森
14年7月10日在21:45

我注意到Mac上的uuidgen全部大写,而Ubuntu(util-linux 2.20.1中的uuidgen)全部小写。为什么会有所不同? Ubuntu也列出了该工具的来源,但在Mac上,没有版本信息,也没有提供它的软件包。

–大卫
15年10月14日在18:27

@David:我相信它是OS X上基本操作系统的一部分。我不知道为什么一个大写而另一个小写。没关系,因为它们都代表有效的十六进制字符(echo -e'f \ nF'| grep'[[:xdigit:]]'输出两行)。如果对您来说确实很重要,并且您拥有Bash 4,则可以将其设置为小写:uuid = $(uuidgen); uuid = $ {uuid ,}或使其大写:uuid = $(uuidgen); uuid = $ {uuid ^^}或类似方法进行tolower()样式测试:if [[$ $ uuid1 ,} == $ {uuid2 ,]]]

–丹尼斯·威廉姆森
2015年10月14日19:30



#2 楼

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

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


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

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


参考文献:



UUID Wikipedia。
FreeBSD错误#186187-[linprocfs] [补丁]模拟/ proc / sys / kernel / random / uuid


评论


这太棒了。

–汤姆·奥康纳(Tom O'Connor)
13年8月7日在13:55

应该避免这种情况,因为它是高度不可移植的(尽管FreeBSD为编写不良的应用程序提供了/ compat / linux / proc / sys / kernel / random / uuid)

–好人
2014年5月22日在1:58

它非常适合initrd图像内使用

–Maximilian
15年6月4日在16:08

这应该是最好的答案!

– dguerri
16年2月10日在0:14

对于真正最少的设置(例如Docker容器),这是一个更好的答案。

– jacderida
16年7月13日在19:35

#3 楼

只是为了完整起见……Debian上还安装了带有dbus软件包的UUID生成器。我想念它早些时候。它可能与e2fsprogs软件包使用相同的算法,但它没有添加破折号,因此对您来说可能更干净:

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6


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

评论


DBus UUID与RFC 4122不相关或不兼容。此外,dbus-uuidgen始终使用Unix时间戳作为最后4个字节。因此,它们可能不适用于某些用途。

–user1686
10年1月16日在15:08

同样适用于Fedora-25 ...

– kmonsoor
17-10-23在11:29

#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
}

[ "q4312078q" == "$BASH_SOURCE" ] && uuid


评论


可以消除T变量,并将for T循环更改为:case $ N in 3 | 5 | 7 | 9)printf'-';; esac(如果需要,在单独的行中分解)。

–丹尼斯·威廉姆森
2014年5月22日14:08

我在github链接的代码中添加了注释,显示了使用case的版本,以消除if语句以及内部的for语句。它使代码更加整洁。请注意,B%15都应为B%16,B%255都应为B%256。

–丹尼斯·威廉姆森
2014年5月22日17:47

将其放在网址上,以便人们可以获取它并尝试使用<(curl url)或其他任何内容

–MrCholo
19年5月23日在5:57

#5 楼

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

od -x /dev/urandom | head -1 | awk '{OFS="-"; print ,,,,}'


已在SnowLeopard,Red Hat Valhalla,Solaris 9 4/04及更高版本上进行了测试。我很好奇这是否容易造成非唯一性,但在过去的十年中,我还没有被“咬”过。当然,也可以用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


评论


辉煌!仅一行,没有依赖项,与BSD / macOS兼容...很棒

–迪尼哥
17年1月10日在8:00

不要使用“ tail -1”。如果仅运行“ od -x / dev / urandom”,它将无限期地继续运行,从而连续生成更多行的随机数据。 “ tail -1”可能永远坐在那里,等待“最后一条”线。否则,这是一个很好的解决方案。

– UncaAlby
18年1月18日在19:09



请注意,只有当head输出的行数大于1时,tail才作为可选参数出现在“ explanation”中。此处确保awk接收一行16字节的单行,这不是原始命令的一部分。从od到头的管道已经对管道到尾部-1的输出进行了消毒。以我的经验,尾部永远等待的唯一时间是使用-f参数。如果解释不明确,那么只有在head的输出产生多行时才需要使用tail -1,对此我感到抱歉。

– dan
18年1月19日在23:11

不要使用它,它完全违反了UUID规范。这样,仅版本4 UUID可以是随机的。

– jlh
18年5月14日在15:08

@jlh我不确定为什么这个问题被锁定,但是这里有一个固定版本,可以使这种方法符合UUID-v4:od -x / dev / urandom |头-1 | awk'{OFS =“-”;费用($ 6); sub(/./,“ 4”,$ 5); sub(/./,substr(“ 89ab”,rand()* 4,1),$ 6);打印$ 2 $ 3,$ 4,$ 5,$ 6,$ 7 $ 8 $ 9}'

– Stuart P. Bentley
18-09-29在17:33

#6 楼

只是这样python不会感到被遗忘:

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


要在外壳中使用它:

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


有关可生成的UUIDS的类型,请参见Python文档UUID。

要在非系统计算机上生成与系统ID兼容的文件,您可以使用python这样做:

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


评论


uuid是内置的吗?

–亚历山大·米尔斯(Alexander Mills)
19年5月23日在5:44

python曾经工作过吗?我得到这个`File“ ”,第1行import uuid;打印uuid.uuid1()^ SyntaxError:无效的语法`

–亚历山大·米尔斯(Alexander Mills)
19年5月23日在5:48

对python3使用python3 -c“ import uuid; print(uuid.uuid4())”

– Abdusco
19年7月29日在15:45



#7 楼

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


将其添加到带有反引号或$()表示法的shellscript中将很简单:

评论


+1-帮帮我!

–rafa.ferreira
2011-02-16 13:29

#8 楼

apt-get install uuid


为我工作,然后我运行了uuid

评论


链接到repo或docs pls?

–亚历山大·米尔斯(Alexander Mills)
19年5月23日在5:48

man7.org/linux/man-pages/man8/uuidd.8.html

–约瑟夫
19年5月23日在18:40

#9 楼

我使用Python编写了一个小Bash函数,以批量生成任意数量的UUID:

# uuid [count]
#
# Generate type 4 (random) UUID, or [count] type 4 UUIDs.
function uuid()
{
    local count=1
    if [[ ! -z "" ]]; then
        if [[ "" =~ [^0-9] ]]; then
            echo "Usage: $FUNCNAME [count]" >&2
            return 1
        fi

        count=""
    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"')]))'


#10 楼

请查看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。

评论


完全同意!在我的用例中,它非常完美,因为它还通过-v3 ns:URL定制数据种子机制支持名称间隔。

–罗伯托·安德拉德(Roberto Andrade)
2015年10月6日18:09

#11 楼

我确定有些人会到达这里,只是在寻找一种简单的方法来生成用于其脚本的唯一ID,并且不必是真正的UUID。

如果是这样,您只需执行以下操作,就会生成唯一的ID,直到一秒为止-因此,如果您在一秒钟内多次运行此ID,您仍会得到相同的结果。

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


将基于当前系统时间生成如下所示的ID:


U1454423662


注意:如果重新安装在Linux上,或者在Mac上安装了Coreutils,则可以使用以下代码生成纳秒级的唯一ID:

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


,或者如果您喜欢python,到十亿分之一秒的基本解决方案,几乎可以在任何地方使用,运行:

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


评论


总体而言,这是非常糟糕的做法。现代计算机完全能够并行运行许多事物并快速完成串行任务,但是对于在不到一秒的时间内进行的任何调用,此ID都是相同的。更不用说同时运行此脚本的任何其他计算机。更好但仍然不是更好的选项是mktemp -u,如MYID =“ $(mktemp -u)”所示。如果您有能力放置空的临时文件,直到重新启动,请放置-u:MYID =“ $(mktemp)”

–克里斯·哈灵顿(Chris Harrington)
16年8月21日在14:08



嘿...第二点唯一的优点...我将在上面添加一些说明...

–布拉德公园
16年8月21日在23:22

#12 楼

这个线程以及各种各样的示例对我来说真的很有用。我经常需要来自许多不同环境的uuid函数。虽然我喜欢纯bash的示例,但有时使用其他语言的库会更方便。

因此,为了全面起见,ruby(1.9.3+)具有内置的SecureRandom模块,其中包含许多有用的哈希和id函数。在bash cli中,您可以执行此操作。

ruby -r securerandom -e 'puts SecureRandom.uuid'


#13 楼

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`


评论


多一点解释将对您的回答有所帮助

–戴夫M
18年6月18日在11:58

x = od -X -A n / dev / random |头-1 | cut -c3-38在下面提供了此内容echo $ x 4151540a 1f7d0bef 8a0725fb d26183a3 uuid = echo $ {x} |切-c1-8-echo $ {x} |切-c10-13-echo $ {x} |切-c14-17-echo $ {x} |切-c19-22-echo $ {x} |切-c23-26''echo $ {x} |切-c28-35 echo $ uuid 4151540a-1f7d-0bef-8a07-25fbd26183a3

– andyfff
18年6月25日在10:26

戴夫·M(Dave M),在离开很多年后重返bash,这在我目前的知识中尚处于边缘。希望将其分解会有所帮助。干杯,安迪夫

– andyfff
18年6月25日在10:28

#14 楼

如果您使用的是Java10。

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


评论


Java 10不是bash。

–卡巴斯德
18-09-12在6:27

我只是举了一个例子,说明了他如何在不运行Java程序的情况下在终端上快速生成UUID。人们给出了使用dbus-uuidgen和uuidgen的示例。使用jshell有什么问题?

–允许
18/09/18在14:05



@amit的要点是,您需要给出一个示例,其中可以在bash脚本中使用jshell,而不是将其用作交互式命令。这在原始帖子中非常清楚。

– Samveen
18-09-27在3:59



如果必须执行此操作,则可以回显“ System.out.println(java.util.UUID.randomUUID()。toString())” | /图书馆/Java/JavaVirtualMachines/openjdk-11.0.1.jdk/Contents/Home/bin/jshell -s | grep -v“>”但是它比uuidgen冗长得多。

– mlk
19 Mar 5 '19在14:00