bash에서 UUID를 만드는 방법은 무엇입니까?


185

Java에서는 임의의 UUID 를 작성할 수 있습니다 .

UUID uuid = UUID.randomUUID();

배쉬에서 이것을하는 방법?

답변:


225

e2fsprogs 패키지의 uuidgen일부인 프로그램을 참조하십시오 .

따르면 , libuuid현재의 일부 의 util 리눅스 에서 e2fsprogs에 포함될 폐지되고있다. 그러나 새로운 우분투 시스템에서는 uuidgen이제 uuid-runtime패키지에 들어 있습니다.

UUID를 작성하여 변수에 저장하려면 다음을 수행하십시오.

uuid=$(uuidgen)

내 우분투 시스템에서 알파 문자는 소문자로 출력되고 OS X 시스템에서는 대문자로 출력됩니다 (댓글에서 지적한 David에게 감사드립니다).

위와 같이 생성 한 후 모든 대문자로 전환하려면 :

uuid=${uuid^^}

모든 소문자로 전환하려면 :

uuid=${uuid,,}

예를 들어 UUID가 두 개이고 대소 문자를 무시하고 Bash에서이를 비교하려는 경우 다음 tolower()과 같이 스타일 비교를 수행 할 수 있습니다 .

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

7
이봐, 불공평 해! 내 e2fsprogs는 그와 함께 제공되지 않았습니다! 나는 하나를 원한다, 나는 그것을 어디서 얻는가? (update : ahhh ... debian은 uuid-runtime명백한 이유없이 패키지에
넣었습니다

uuidgen은 freeBSD에 내장되어 있습니다. 항상 e2fsprogs 패키지에있는 것은 아닙니다.
Good Person

1
@Rob : 원래 질문에 답하려면 드라이브 레이블 입니다.
Dennis Williamson

2
Mac의 uuidgen은 모두 대문자로 나오는 반면 Ubuntu (util-linux 2.20.1의 uuidgen)는 모두 소문자로 나타납니다. 왜 차이점이 있습니까? 또한 우분투는 도구가 어디에서 왔는지 Mac에 나열되어 있으며 버전 정보가 없거나 패키지가 어디인지 알려줍니다.
David

1
@David : OS X에서 기본 운영 체제의 일부라고 생각합니다. 왜 하나는 대문자이고 다른 하나는 더 낮은 지 모르겠습니다. 유효한 16 진 문자 ( echo -e 'f\nF' | grep '[[:xdigit:]]'두 줄을 모두 출력)를 나타내므로 실제로 중요하지 않습니다 . 당신을 위해 문제를 수행하고 배시 넷이 있다면, 당신은 그것을 소문자를 만들기 위해이 작업을 수행 할 수 있습니다 uuid=$(uuidgen); uuid=${uuid,,}또는이는 대문자로 만들기 위해 : uuid=$(uuidgen); uuid=${uuid^^}또는이 라인을 따라 뭔가는 할 tolower()스타일 테스트 :if [[ ${uuid1,,} == ${uuid2,,} ]]
데니스 윌리엄슨

168

외부 의존성을 추가하지 않고 다양성을 추가하려면 Linux에서 다음을 수행 할 수 있습니다.

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

Linux 호환 계층 (linuxulator?) 에서 FreeBSD의 나쁜 관행을 전파하려면 ,

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

참고 문헌 :


19
대단해.
Tom O'Connor

3
이식성이 높지 않기 때문에 피해야한다 (FreeBSD는 잘못 작성된 애플리케이션을 위해 / compat / linux / proc / sys / kernel / random / uuid를 제공하지만)
Good Person

1
initrd 이미지 내부에서 사용하기에 적합
Maximilian

2
이것이 가장 좋은 대답이어야합니다!
dguerri

6
이것은 Docker 컨테이너와 같이 실제로 최소 설정에 대한 더 나은 대답입니다.
jacderida

34

완벽을 기하기 위해 dbus데비안 패키지 에는 UUID 생성기가 설치되어 있습니다. 일찍 둘러보고 싶었습니다. 아마도 e2fsprogs 패키지와 동일한 알고리즘이지만 대시를 추가하지 않으므로 약간 더 깨끗할 수 있습니다.

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

$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6

Grawity는 안전 팁을 추가합니다. "DBus UUID는 RFC 4122 와 관련이 없거나 RFC 4122 와 호환되지 않습니다 . 또한 dbus-uuidgen은 항상 마지막 타임 스탬프를 마지막 4 바이트로 사용하므로 일부 용도에는 적합하지 않을 수 있습니다." (감사합니다, Grawity, 맨 페이지에서 그 점을 발견해야합니다.)


7
DBus UUID는 RFC 4122와 관련이 없거나 호환되지 않습니다. 또한 dbus-uuidgen항상 유닉스 타임 스탬프를 마지막 4 바이트로 사용합니다. 따라서 일부 용도에는 적합하지 않을 수 있습니다.
grawity

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(원하는 경우 별도의 라인에서 세분화).
Dennis Williamson

1
내부 명령문 뿐만 아니라 명령문 case을 제거하는 데 사용하는 버전을 보여주는 github 링크의 코드에 주석을 추가했습니다 . 코드가 훨씬 깔끔해집니다. 둘 다 이어야 하고 이어야합니다 . ifforB%15B%16B%255B%256
Dennis Williamson

사람들이 소스와 그것을 시도 할 수 있도록 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 진 덤프)에는 16 비트 출력 스위치 (-x)가있어 라인 당 16 바이트를 생성합니다.

head-n [| tail -1] (여기서 n> 0)은 이전 출력의 한 줄만 추출합니다.

awkprintFieldSeparator를 print 문에서 쉼표가 나타나는 곳마다 하이픈으로 설정합니다. 필드 2-9를 독립적으로 지정하여 하이픈을 제어하고 각 출력 줄 앞에 'od'가 붙는 인덱스 / 오프셋 카운터를 제거합니다.

결과는 8-4-4-4-12소문자 패턴입니다 a-f0-9.

993bb8d7-323d-b5ee-db78-f976a59d8284

1
훌륭한! 의존성이없는 단 하나의 라인, BSD / macOS 호환 ... 훌륭한
dinigo

"꼬리 -1"을 사용 하지 마십시오 . "od -x / dev / urandom"만 단독으로 실행하면 무한정으로 계속 진행되어 더 많은 무작위 데이터 라인이 계속 생성됩니다. "꼬리 -1"은 "마지막"줄을 영원히 기다릴 수 있습니다. 그렇지 않으면 좋은 해결책입니다.
UncaAlby

head가 출력하는 라인 수가 1보다 큰 경우 tail은 선택적 설명으로 "설명"에만 있습니다. awk로 16 바이트의 단일 행을 수신 할 수 있으며 원래 명령의 일부가 아닙니다. od에서 향하는 파이프는 이미 tail -1까지의 파이프 출력을 위생 처리합니다. 내 경험에 따르면 시간 꼬리가 영원히 기다리는 유일한 시간은 -f 인수입니다. head -1의 출력이 두 줄 이상을 생산할 때만 tail -1의 사용이 필요하다는 설명이 명확하지 않은 경우 사과드립니다.
dan

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}'
Stuart P. Bentley

14

그래서 파이썬은 빠진 느낌이 들지 않습니다.

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 -c 'import re; import uuid; print re.sub("-","",str(uuid.uuid4()))' \
 > /etc/machine-id

UUID가 내장되어 있습니까?
Alexander Mills

파이썬은 일한 적이 있습니까? 나는``파일 "<string>", line 1 import uuid; print uuid.uuid1 () ^ SyntaxError : 유효하지 않은 구문`
Alexander Mills

1
python3 -c "import uuid; print(uuid.uuid4())"python3에 사용
abdusco

11

Perl은 e2fsprogs패키지를 기반으로 UUID 라이브러리를 제공 합니다. 내 데비안 시스템에서는 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

파이썬을 사용하여 임의의 수의 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 (예 : e2fsprogs) 라이브러리가 처리 할 수 ​​없었던 버전 3 및 버전 5 UUID를 올바르게 처리합니다 . 다행히도 openSUSE는 주요 저장소 중 하나에 있습니다. Windows (예 : Cygwin) 또는 MySQL에서 작동하는 버전을 얻는 것이 잘못되었습니다. v3 및 v5 UUID가 실제로 필요하므로 Linux / PostgreSQL / Python으로 전환해야 할 때인 것 같습니다 (그리고 SQLyog GUI를 MySQL / MariaDB로 너무 좋아했습니다).


완전히 동의하십시오! 내 유스 케이스의 경우 -v3 ns:URL custom-data시드 메커니즘을 통해 네임 스페이스를 지원하기 때문에 완벽했습니다 .
Roberto Andrade

1

일부는 여기에 도착할 것이라고 확신하며 스크립트에서 사용할 고유 ID를 생성하는 쉬운 방법을 찾고 있으며 실제 UUID 일 필요는 없습니다.

그렇다면 다음을 수행하면 초 단위로 고유 한 ID가 생성되므로 1 초 이내에 여러 번 실행하면 여전히 동일한 결과를 얻을 수 있습니다.

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

현재 시스템 시간을 기준으로 다음과 같은 ID를 생성합니다.

U1454423662

참고 : Linux를 사용하거나 Mac에 Coreutils를 설치 한 경우 다음을 사용하여 나노초에 고유 한 ID를 생성 할 수 있습니다.

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

또는 거의 모든 곳에서 작동 해야하는 나노 기반의 파이썬 기반 솔루션을 선호하는 경우 다음을 실행하십시오.

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

1
이것은 전반적으로 매우 나쁜 습관입니다. 최신 컴퓨터는 많은 작업을 병렬로 완벽하게 실행하고 직렬 작업을 신속하게 완료 할 수 있지만이 ID는 1 초 내에 다른 호출에서 동일합니다. 이 스크립트를 동시에 실행하는 다른 컴퓨터는 말할 것도 없습니다. 더 낫지 만 여전히 낫지 않은 옵션은 mktemp -u에서와 같습니다 MYID="$(mktemp -u)". 재부팅 할 때까지 빈 임시 파일을 배치 할 여유가 있다면 다음을 삭제하십시오 -u.MYID="$(mktemp)"
Chris Harrington

이봐 .. 두 번째 점에만 유일하게 좋은 점 ... 위에 몇 가지 메모를 추가하겠습니다 ...
Brad Parks

1

이 예제는 다양한 예제와 함께 정말 유용했습니다. 여러 환경에서 UUID 기능이 자주 필요합니다. 그리고 순수한 bash 예제를 좋아하지만 때로는 다른 언어의 라이브러리를 사용하는 것이 더 편리합니다.

따라서 철저한 관리를 위해 루비 (1.9.3+)에는 유용한 해시 및 ID 함수가 다수 포함 된 내장 SecureRandom 모듈이 있습니다. 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
조금 더 설명하면 답변에 도움이 될 것입니다
Dave 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

Dave M, 몇 년 후 배쉬 작업을 다시 한 번했는데, 이것은 현재 알려진 지식의 가장자리에 있습니다. 약간의 도움이되기를 바랍니다. 건배, andyfff
andyfff

-1

Java 10을 사용중인 경우

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

Java 10은 bash가 아닙니다.
kasperd

방금 Java 프로그램을 실행하지 않고 터미널에서 UUID를 얼마나 빨리 생성 할 수 있는지에 대한 예를 들었습니다. 사람들은 dbus-uuidgenuuidgen 의 사용 예를 들었습니다 . jshell 사용에있어 무엇이 문제입니까?
amit

1
@amit 점은 예를 들어 줄 필요가있다 jshell할 수있다 bash는 스크립트에 사용 하고, 하지 대화식 명령 등을 . 그것은 원래 게시물에서 매우 분명합니다.
Samveen

이 목록에 뭔가를해야한다면 할 수는 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.