program tip

유닉스 쉘에서 임의의 파일 이름 생성

radiobox 2020. 10. 31. 09:34
반응형

유닉스 쉘에서 임의의 파일 이름 생성


유닉스 셸 (예 : tcshell)에서 임의의 파일 이름을 생성하고 싶습니다. 파일 이름은 임의의 32 16 진수 문자로 구성되어야합니다. 예 :

c7fdfc8f409c548a10a0a89a791417c5

(필요한 것을 추가합니다). 요점은 프로그램에 의존하지 않고 쉘에서만 할 수 있다는 것입니다.


Linux를 사용한다고 가정하면 다음이 작동합니다.

cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32

이것은 시스템이 엔트로피에서 낮게 실행되지만 (리눅스에서) 종료가 보장되는 경우에만 의사 랜덤입니다. 당신은 진정으로 임의의 데이터, 고양이가 필요한 경우 /dev/random대신을 /dev/urandom. 이 변경은 진정한 무작위 출력을 생성 할 수있는 충분한 엔트로피를 사용할 수있을 때까지 코드 블록을 만들어 코드 속도를 늦출 수 있습니다. 대부분의 경우의 출력 /dev/urandom은 충분히 무작위입니다.

OS X 또는 다른 BSD를 사용하는 경우 다음과 같이 수정해야합니다.

cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32

유닉스 mktemp 명령을 사용하지 않는 이유 :

$ TMPFILE=`mktemp tmp.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` &&  echo $TMPFILE
tmp.MnxEsPDsNUjrzDIiPhnWZKmlAXAO8983

하나의 명령, 파이프, 루프 없음 :

hexdump -n 16 -v -e '/1 "%02X"' -e '/16 "\n"' /dev/urandom

줄 바꿈이 필요하지 않은 경우 (예 : 변수에서 사용하는 경우) :

hexdump -n 16 -v -e '/1 "%02X"' /dev/urandom

"16"을 사용하면 32 개의 16 진수가 생성됩니다.


당신은 아마 대답의 각에서 발견, 당신은 일반적으로 "프로그램에 리조트"에.

그러나 외부 실행 파일 을 사용 하지 않고 Bash 및 ksh에서 :

string=''; for i in {0..31}; do string+=$(printf "%x" $(($RANDOM%16)) ); done; echo $string

zsh에서 :

string=''; for i in {0..31}; do string+=$(printf "%x" $(($RANDOM%16)) ); dummy=$RANDOM; done; echo $string

소문자로 변경 x대문자로 형식 문자열을 X알파벳 진수 문자 대문자를 만들 수 있습니다.

다음은 명시 적 루프없이 Bash에서 수행하는 또 다른 방법입니다.

printf -v string '%X' $(printf '%.2s ' $((RANDOM%16))' '{00..31})

다음에서 "첫 번째"와 "두 번째" printf는 행에 나타나는 순서가 아닌 실행되는 순서를 나타냅니다.

이 기술은 중괄호 확장을 사용하여 32 개의 난수 mod 16 뒤에 각각 공백과 중괄호 안에있는 범위의 숫자 중 하나와 다른 공백 (예 :)의 목록을 생성합니다 11 00. 해당 목록의 각 요소에 대해 첫 번째 printf는 형식 문자열 ( %.2)을 사용하여 처음 두 문자를 제외한 모든 문자를 제거하고 한 자리 뒤에 공백을 두거나 두 자리 숫자를 남겨 둡니다. 형식 문자열의 공백은 각 출력 번호 사이에 적어도 하나의 공백이 있는지 확인합니다.

첫 번째를 포함하는 명령 대체 printf는 인용되지 않으므로 단어 분할이 수행되고 각 숫자는 printf별도의 인수로 두 번째 이동합니다 . 거기에서 숫자는 %X형식 문자열에 의해 16 진수로 변환되고 공백없이 서로 추가되고 (형식 문자열에 아무것도 없기 때문에) 결과는라는 변수에 저장됩니다 string.

printf의 형식 문자열을 차지하고보다 더 많은 인수를 수신 그들은 모두 소모 될 때까지, 형식은 차례로 각 인수에 적용됩니다. 인수가 더 적 으면 일치하지 않는 형식 문자열 (부분)이 무시되지만이 경우에는 적용되지 않습니다.

Bash 3.2, 4.4 및 5.0-alpha에서 테스트했습니다. 그러나 zsh (5.2) 또는 ksh (93u +) RANDOM에서는 해당 쉘의 중괄호 확장에서 한 번만 평가 되기 때문에 작동하지 않습니다 .

0에서 32767 사이의 값에 mod 연산자를 사용하기 때문에 스 니펫을 사용하는 자릿수 분포가 왜곡 될 수 있습니다 ( 처음에 숫자가 의사 랜덤 이라는 사실은 말할 것도 없습니다 ). 그러나 우리는 mod 16을 사용하고 32768은 16으로 나눌 수 있으므로 여기서는 문제가되지 않습니다.

어쨌든 올바른 방법 mktempOleg Razgulyaev의 답변 에서와 같이 사용 하는 것입니다.


zsh에서 테스트되었으며 BASH 호환 쉘에서 작동해야합니다!

#!/bin/zsh

SUM=`md5sum <<EOF
$RANDOM
EOF`

FN=`echo $SUM | awk '// { print $1 }'`

echo "Your new filename: $FN"

예:

$ zsh ranhash.sh
Your new filename: 2485938240bf200c26bb356bbbb0fa32
$ zsh ranhash.sh
Your new filename: ad25cb21bea35eba879bf3fc12581cc9

이 답변은 fmarks와 매우 유사하기 때문에 실제로 인정할 수는 없지만 cat 및 tr 명령 조합이 상당히 느리고이 버전이 상당히 빠르다는 것을 알았습니다. hexdump가 필요합니다.

hexdump -e '/1 "%02x"' -n32 < /dev/urandom

또 다른 방법 [tm].

R=$(echo $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM | md5 | cut -c -8)
FILENAME="abcdef-$R"

첫 번째 대답은 좋지만 필요하지 않은 경우 왜 포크 고양이입니다.

tr -dc 'a-f0-9' < /dev/urandom | head -c32

에서 16 바이트를 /dev/random가져 와서 16 진수로 변환하고 첫 번째 줄을 가져 와서 주소를 제거하고 공백을 제거합니다.

head /dev/random -c16 | od -tx1 -w16 | head -n1 | cut -d' ' -f2- | tr -d ' '

물론 "프로그램에 의존하지 않는다"는 것은 "쉽게 사용할 수있는 프로그램 만 사용하는 것"을 의미합니다.


이 주제에 (아마도) 더 나은 솔루션을 추가하기를 바랍니다.

주의 : 이것은 단지와 함께 작동 bash4일부의 구현 mktemp(예를 들어, GNU의 하나)

이 시도

fn=$(mktemp -u -t 'XXXXXX')
echo ${fn/\/tmp\//}

이것은.보다 두 head /dev/urandom | tr -cd 'a-f0-9' | head -c 32배 빠르며 cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32.

기준:

mktemp 사용 :

#!/bin/bash
# a.sh
for (( i = 0; i < 1000; i++ ))
do
    fn=$(mktemp -u -t 'XXXXXX')
    echo ${fn/\/tmp\//} > /dev/null
done

time ./a.sh 
./a.sh  0.36s user 1.97s system 99% cpu 2.333 total

그리고 나머지:

#!/bin/bash
# b.sh
for (( i = 0; i < 1000; i++ ))
do
    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 32 > /dev/null
done

time ./b.sh 
./b.sh  0.52s user 20.61s system 113% cpu 18.653 total

If you are on Linux, then Python will come pre-installed. So you can go for something similar to the below:

python -c "import uuid; print str(uuid.uuid1())"

If you don't like the dashes, then use replace function as shown below

python -c "import uuid; print str(uuid.uuid1()).replace('-','')"

Another thing you can add is running the date command as follows:

date +%S%N

Reads nonosecond time and the result adds a lot of randomness.


If you have openssl in your system you can use it for generating random hex (also it can be -base64) strings with defined length. I found it pretty simple and usable in cron in one line jobs.

 openssl rand -hex 32
 8c5a7515837d7f0b19e7e6fa4c448400e70ffec88ecd811a3dce3272947cb452

uuidgen generates exactly this, except you have to remove hyphens. So I found this to be the most elegant (at least to me) way of achieving this. It should work on linux and OS X out of the box.

uuidgen | tr -d '-'

참고URL : https://stackoverflow.com/questions/2793812/generate-a-random-filename-in-unix-shell

반응형