在unix shell中生成一个随机文件名
我想在unix shell中生成一个随机的文件名(比如说tcshell)。 文件名应该由随机的32个hex字母组成,例如:
c7fdfc8f409c548a10a0a89a791417c5
(我将添加任何必要的)。 重点是只能在没有诉诸程序的情况下才能做到这一点。
假设你在Linux上,下面的工作:
cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32
如果你的系统在熵上运行的很低,但是(在Linux上)保证终止,这只是伪随机的。 如果你需要真正的随机数据,cat /dev/random
而不是/dev/urandom
。 这个改变会让你的代码阻塞,直到有足够的熵产生真正的随机输出,所以它可能会减慢你的代码。 对于大多数用途, /dev/urandom
的输出是足够随机的。
如果您在OS X或其他BSD上,则需要将其修改为以下内容:
cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32
为什么不使用unix mktemp命令:
$ TMPFILE=`mktemp tmp.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` && echo $TMPFILE tmp.MnxEsPDsNUjrzDIiPhnWZKmlAXAO8983
一个命令,没有pipe道,没有循环:
hexdump -n 16 -v -e '/1 "%02X"' -e '/16 "\n"' /dev/urandom
如果你不需要换行符,例如当你在一个variables中使用它:
hexdump -n 16 -v -e '/1 "%02X"' /dev/urandom
使用“16”会生成32个hex数字。
在zsh中testing过,应该可以和任何BASH兼容的shell一起工作!
#!/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
正如你从每个答案中可能注意到的那样,你通常不得不 “求助于一个程序”。
但是,不使用任何外部可执行文件 ,在Bash和ksh中:
for i in {0..31}; do string+=$(printf "%x" $(($RANDOM%16)) ); done; echo $string
在zsh:
for i in {0..31}; do string+=$(printf "%x" $(($RANDOM%16)) ); dummy=$RANDOM; done; echo $string
请注意,由于使用mod运算符的值介于0到32767之间,所以使用上面的代码片段进行的数字分布将会发生偏斜(更不用说事实上数字是伪随机的了)。
在任何情况下,正确的方法是使用mktemp
作为oraz的答案。
还有另一种方式。
R=$(echo $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM | md5 | cut -c -8) FILENAME="abcdef-$R"
从/dev/random
抓取16个字节,将它们转换为hex,取第一行,删除地址,删除空格。
head /dev/random -c16 | od -tx1 -w16 | head -n1 | cut -d' ' -f2- | tr -d ' '
假设“不诉诸于程序”意味着“只使用容易获得的程序”,当然。
如果你在Linux上,那么Python将预先安装。 所以你可以去找类似于下面的东西:
python -c "import uuid; print str(uuid.uuid1())"
如果您不喜欢破折号,请使用replacefunction,如下所示
python -c "import uuid; print str(uuid.uuid1()).replace('-','')"
希望增加(也许)更好的解决scheme,这个话题。
注意:这只适用于bash4
和mktemp
一些实现(例如,GNU的)
尝试这个
fn=$(mktemp -u -t 'XXXXXX') echo ${fn/\/tmp\//}
这个head /dev/urandom | tr -cd 'a-f0-9' | head -c 32
快两倍 head /dev/urandom | tr -cd 'a-f0-9' | head -c 32
head /dev/urandom | tr -cd 'a-f0-9' | head -c 32
,比cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32
快8倍 cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32
cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32
。
基准testing:
用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
你可以添加的另一件事是运行date命令如下:
date +%S%N
读取非秒时间,结果增加了很多随机性。