我想在Unix shell(例如tcshell)中生成一个随机的文件名。该文件名应由随机的32个十六进制字母组成,例如:
c7fdfc8f409c548a10a0a89a791417c5
(我会添加必要的内容)。重点是只能使用shell而不需要使用程序来完成。
假设您使用的是Linux系统,以下内容应该有效:
cat /dev/urandom | tr -cd 'a-f0-9' | head -c 32
如果你的系统熵值不足,那么以下方法只是伪随机,但(在Linux上)保证能够终止。如果需要真正的随机数据,请使用/dev/random
而不是/dev/urandom
。这种更改将阻塞代码,直到足够的熵可用以生成真正的随机输出,因此可能会使代码减慢速度。对于大多数用途,/dev/urandom
的输出已经足够随机了。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
--dry-run
标志来防止文件被创建。这当然会引起可能的竞态条件。 - glenn jackman一个命令,不需要管道和循环:
hexdump -n 16 -v -e '/1 "%02X"' -e '/16 "\n"' /dev/urandom
如果您不需要换行符,例如在将其用作变量时:
hexdump -n 16 -v -e '/1 "%02X"' /dev/urandom
使用 "16" 会生成 32 个十六进制数字。
hexdump
来做到这一点。 - avetiskuuidgen
生成的结果与此完全相同,只是需要删除连字符。 因此,我发现这是实现这一目标最优雅(至少对我来说)的方法。它应该可以在Linux和OS X上直接使用。
uuidgen | tr -d '-'
正如你从每个答案中可能注意到的那样,通常情况下你必须“求助于程序”。
然而,在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
指的是它们执行的顺序,而不是它们在行中出现的顺序。11 00
)。对于该列表的每个元素,第一个printf
使用其格式字符串(%.2
)剥离除前两个字符之外的所有内容,留下单个数字后跟一个空格或两个数字。格式字符串中的空格确保输出数字之间至少有一个空格。printf
的命令替换未加引号,因此进行了单词分割,并将每个数字作为单独的参数传递给第二个printf
。在那里,数字通过%X
格式字符串转换为十六进制,并且它们附加在一起而没有空格(因为格式字符串中没有空格),结果存储在名为string
的变量中。printf
接收到的参数比其格式字符串要求的多时,该格式会依次应用于每个参数,直到它们全部被消耗完。如果参数较少,则忽略未匹配的格式字符串(部分),但在这种情况下不适用。RANDOM
仅在大括号扩展中求值一次。mktemp
。#!/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
16^32
。 - Dennis Williamsonmd5sum
二进制文件的系统。例如,FreeBSD和OSX有一个/sbin/md5
,它具有相同的目的但使用不同的选项语法。 - ghoti另一种方式[tm]。
R=$(echo $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM | md5 | cut -c -8)
FILENAME="abcdef-$R"
这个答案与fmarks非常相似,所以我无法真正地为它负责,但我发现猫和tr命令组合相当慢,而我发现这个版本要快得多。您需要使用hexdump。
hexdump -e '/1 "%02x"' -n32 < /dev/urandom
您可以添加的另一件事是运行以下日期命令:
date +%S%N
读取纳秒时间并将结果添加到大量随机数中。
tr -dc 'a-f0-9' < /dev/urandom | head -c32