在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,这个话题。

注意:这只适用于bash4mktemp一些实现(例如,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 

读取非秒时间,结果增加了很多随机性。