bashでUUIDを作成する方法は?


185

Javaでは、ランダムなUUIDを作成できます。

UUID uuid = UUID.randomUUID();

Bashでこれを行う方法は?

回答:


225

e2fsprogsパッケージのuuidgen一部であるプログラムを参照してください。

よれば、このlibuuid今の一部のutil-linuxのとe2fsprogsのに含めることは、段階的に廃止されています。ただし、新しいUbuntuシステムでuuidgenは、uuid-runtimeパッケージに含まれるようになりました。

uuidを作成して変数に保存するには:

uuid=$(uuidgen)

Ubuntuシステムでは、アルファ文字は小文字で出力され、OS Xシステムでは、大文字で出力されます(コメントで指摘してくれたDavidに感謝します)。

上記のように生成した後、すべて大文字に切り替えるには:

uuid=${uuid^^}

すべて小文字に切り替えるには:

uuid=${uuid,,}

たとえば、2つのUUIDがあり、それらを大文字と小文字を無視してBashで比較したい場合、次のtolower()ようなスタイル比較を行うことができます。

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

7
おい、フェアじゃない!私のe2fsprogsには付属していませんでした!欲しいのですが、どこで入手できますか?(更新:ああ... debianはuuid-runtime明白な理由なしにパッケージに貼り付けます... +1します)
奇抜なキホーテ

uuidgenはfreeBSDに組み込まれています。常にe2fsprogsパッケージに含まれているわけではありません。
善人

1
@Rob:元の質問に答えるために、それはドライブラベルです
デニスウィリアムソン14

2
Macのuuidgenはすべて大文字で、Ubuntu(util-linux 2.20.1のuuidgen)はすべて小文字で出力します。なぜ違いがあるのですか?また、Ubuntuはツールの提供元をリストしましたが、Macではバージョン情報もパッケージの提供元もありません。
デビッド

1
@David:OS Xの基本オペレーティングシステムの一部だと思います。一方が大文字でもう一方が小文字である理由がわかりません。どちらも有効な16進文字を表す(echo -e 'f\nF' | grep '[[:xdigit:]]'両方の行を出力する)ので、実際には問題ではありません。あなたにとって重要であり、Bash 4を持っている場合、これを行うことで小文字にすることができます:uuid=$(uuidgen); uuid=${uuid,,}またはこれにより大文字にする:uuid=$(uuidgen); uuid=${uuid^^}またはこれらの行に沿ってtolower()スタイルテストを行う:if [[ ${uuid1,,} == ${uuid2,,} ]]
デニスウィリアムソン

168

Linuxで外部依存関係を追加せずに多様性を追加するには、次のようにします。

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

FreeBSD上で、Linux互換性レイヤー(linuxulator?)の下で悪い習慣を広めるために、

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

参照:


19
これはすごい。
トム・オコナー

3
移植性が非常に低いので、これは避けるべきです(ただし、FreeBSDは、不十分な記述のアプリケーション用に/ compat / linux / proc / sys / kernel / random / uuidを提供します)
グッドパーソン

1
これは、initrdイメージの中の使用のために完璧にフィット
マクシミリアン

2
これが最良の答えです!
-dguerri

6
これは、Dockerコンテナーのような本当に最小限のセットアップの場合に適した答えです。
ジャクデリダ

34

完全を期すために... dbusDebianには、パッケージと共にインストールされるUUIDジェネレータもあります。以前見回すのが恋しかった。これはおそらくe2fsprogsパッケージと同じアルゴリズムですが、ダッシュは追加されないため、少しわかりやすいかもしれません。

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawityは安全性のヒントを追加します:「DBus UUIDはRFC 4122に関連していないか、RFC 4122と互換性がありません。さらに、dbus-uuidgenは常に最後の4バイトとしてUnixタイムスタンプを使用します。(ありがとう、Grawity、それをマンページで見つけたはずです。)


7
DBus UUIDは、RFC 4122に関連していないか、RFC 4122と互換性がありませんdbus-uuidgen。さらに、最後の4バイトとして常にUnixタイムスタンプを使用します。そのため、一部の用途には適さない場合があります。
悲惨さ

同じことがFedora-25でも機能します...
kmonsoor

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

T変数を排除することができ、for Tループに変更することができる:case $N in 3 | 5 | 7 | 9) printf '-';; esac(好ましい場合は別々の行に出破壊します)。
デニスウィリアムソン

1
ステートメントと内部ステートメントcaseを削除するために使用しているバージョンを示すgithubリンクのコードにコメントを追加しました。これにより、コードがよりきれいになります。両方があることに注意する必要がありますし、する必要があります。ifforB%15B%16B%255B%256
デニスウィリアムソン

人々はそれを調達し、それを試すことができますので、URLからオンラインでそれを置く source <(curl url)か、何でも
MrCholo

19

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 (8進ダンプ)には、1行あたり16バイトを生成する16進出力スイッチ(-x)があります。

head-n [| tail -1](n> 0)は、前の出力の1行のみを抽出します。

awkprintステートメントでコンマが出現するすべての場所でOutputFieldSeparatorをハイフンに設定します。フィールド2〜9を個別に指定することにより、ハイフンを制御し、「od」が出力の各行の前に付くインデックス/オフセットカウンターを取り除きます。

結果は8-4-4-4-12小文字のパターンですa-f0-9

993bb8d7-323d-b5ee-db78-f976a59d8284

1
ブリリアント!依存関係のない1行だけで、BSD / macOSと互換性があります...すばらしい
dinigo

「tail -1」は使用しないでください。単独で「od -x / dev / urandom」を実行すると、無期限に実行され、より多くの行のランダムデータが継続的に生成されます。「末尾-1」は、「最後の」行を待つために永遠にそこに座っているだけです。そうでなければ、それは良い解決策です。
UncaAlby

なお、headが出力する行数が1を超える場合、tailはオプションのパラメーターとして「説明」にのみ含まれます。そこにawkで16バイトの単一行を確実に受信するためにあり、元のコマンドの一部ではありません。odから頭へのパイプは、すでにtail -1へのパイプの出力をサニタイズします。私の経験では、テールが永遠に待機する唯一の時間は、-f引数を使用することです。headの出力が複数の行を生成する場合にのみtail -1の使用が必要であると説明している場所で説明が明確でない場合は謝罪します。
ダン

2
これ使用しないでください。UUIDの仕様に完全に違反します。このようにランダムに使用できるのはバージョン4 UUIDのみです。
jlh

3
@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}'
スチュアートP.ベントレー

14

pythonが取り残されているとは感じません。

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

シェルで使用するには:

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

生成できるUUIDの種類については、PythonドキュメントのUUIDを参照してください。

非systemdマシンでsystemd machine-id互換ファイルを生成するには、pythonを使用して次のようにします。

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

uuidは組み込みですか?
アレクサンダーミルズ

pythonは動作しましたか?この `File" <string> "の1行目のimport uuidを取得します。print uuid.uuid1()^ SyntaxError:無効な構文 `
Alexander Mills

1
python3 -c "import uuid; print(uuid.uuid4())"python3の使用
abdusco

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

これは、バックスクリプトまたは$()表記を使用してシェルスクリプトに追加するのは簡単です。

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

+1-たくさん助けて!
rafa.ferreira


1

Pythonを使用して、任意の数のUUIDを一括生成する小さなBash関数を作成しました。

# 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

OSSP UUIDライブラリ(http://www.ossp.org/pkg/lib/uuid/)を見て、インストールを検討してください。一部のプロジェクトではオプションとして提供しています(例:PostgreSQL)。 バージョン3およびバージョン5のUUIDを適切に処理します。これは、インストールされている(e2fsprogsなど)ライブラリが処理できる範囲を超えていました。幸いなことに、openSUSEにはメインリポジトリの1つに含まれています。Windows(Cygwinなど)またはMySQLで動作するバージョンを取得することは、失敗です。v3とv5のUUIDが本当に必要なので、Linux / PostgreSQL / Pythonに切り替える時期です(そして、SQLyog GUIからMySQL / MariaDBが大好きです)。


完全に同意します!私のユースケースでは、-v3 ns:URL custom-dataシードメカニズムを介したネームスペースもサポートしているため、完璧でした。
ロベルトアンドレーデ

1

ここに到着する人もいると思いますが、スクリプトで使用する一意のIDを生成する簡単な方法を探しているだけで、真のUUIDである必要はありません。

その場合、次の操作を行うだけで、秒まで一意のIDが生成されます。したがって、1秒以内にこれを複数回実行しても、同じ結果が得られます。

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

現在のシステム時刻に基づいて、次のようなIDを生成します。

U1454423662

注:Linuxを使用している場合、またはCoreutilsをMacにインストールしている場合は、次を使用してナノ秒に対する一意のIDを生成できます。

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

または、ほとんどすべての場所で機能するナノ秒までのPythonベースのソリューションを好む場合は、次を実行します。

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

1
これは全体的に非常に悪い習慣です。現代のコンピューターは、多くのことを並行して実行し、シリアルタスクを迅速に完了することができますが、このIDは、1秒以内の呼び出しでも同じです。このスクリプトを同時に実行している他のコンピューターは言うまでもありません。より良いが、まだ素晴らしいではないオプションは、のmktemp -uようになりMYID="$(mktemp -u)"ます。あなたは、再起動するまで転がっ空の一時ファイルを持っている余裕ができた場合は、ドロップ-uMYID="$(mktemp)"
クリス・ハリントン

ねえ...第二の点にのみユニークに良い点...私は...上にいくつかのメモを追加します
ブラッド・パークス

1

さまざまな例のあるこのスレッドは、私にとって本当に役に立ちました。さまざまな環境のuuid関数が頻繁に必要です。また、純粋なbashの例は大好きですが、別の言語のライブラリを使用する方が便利な場合があります。

そのため、万全を期すために、ruby(1.9.3+)には組み込みのSecureRandomモジュールがあり、多くの便利なハッシュ関数とid関数が含まれています。bash cliから、これを行うことができます。

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

0
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`

3
もう少し説明があなたの答えを助けるだろう
デイブM

X =は、od -X -A n /dev/random | head -1 | cut -c3-38 あなたに与えます。この下のエコー$ X 4151540a 1f7d0bef 8a0725fb d26183a3 UUID = echo ${x} | cut -c1-8- echo ${x} | cut -c10-13- echo ${x} | cut -c14-17- echo ${x} | cut -c19-22- echo ${x} | cut -c23-26``echo ${x} | cut -c28-35 $ UUID 4151540a-1f7d0bef-8a07-25fbd26183a3エコー
andyfff

デイブ・M、何年も後にバッシュをして、これは私の現在の知識の端に非常にあります。それを少し分解することを願っています。乾杯、andyfff
andyfff

-1

Java 10を使用している場合。

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

Java 10はbashではありません。
カスペルド

Javaプログラムを実行せずに、端末でUUIDをどれだけ迅速に生成できるかについて例を示しました。人々はdbus-uuidgenuuidgenの使用例を挙げました。jshellの使用の何が問題になっていますか?
アミット

1
@amitは、インタラクティブなコマンドとしてではなく、bashスクリプト使用jshellできる例を提供する必要があるということです。それは元の投稿で非常に明確です。
サンビーン

あなたが何かをリストしなければならないなら、あなたはecho "System.out.println(java.util.UUID.randomUUID().toString())" | /Library/Java/JavaVirtualMachines/openjdk-11.0.1.jdk/Contents/Home/bin/jshell -s | grep -v ">" それをすることができますが、それはよりもずっと長いですuuidgen
mlk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.