Answers:
根据收到的错误消息,我认为/ dev / urandom不是问题。如果是这样,我希望会出现类似“没有这样的文件或目录”的错误。
我搜索了收到的错误消息,并发现了这个错误消息,这似乎与您的问题有关:http : //nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence
基本上,通过在tr
命令前添加来指定语言环境LC_CTYPE=C
:
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
urandom
或random
吗?它们是在实际文件系统上不存在的特殊的神奇“文件”吗?(另外,我建议进行编辑以帮助缓解链接丢失)
locate
不会直接搜索您的文件系统,而是使用预建的数据库查找您的查询。该数据库很可能配置为忽略/ dev /和其他“特殊”文件系统。
/dev
。去搞清楚。但是再次感谢您的帮助。
LC_ALL=C
做花招。
tr
信息的最新博客页面。
您tr
尝试将其输入解释为UTF-8编码的文本。因此它将抱怨并中止无效的UTF-8的第一个字节序列。tr
以LC_ALL=C
或加上前缀LC_CTYPE=C
会将变量导出到的环境中tr
,从而将其本地字符集的概念更改为C标准,即,所有内容只是一个不透明字节序列。
顺便说一句,\)-+
您命令中的顺序是故意的吗?这也包括*
您已经包含的内容,但不包括-
您可能想要的本身。最好改写其中之一:
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom
正如其他人所指出的,你的问题不是/dev/urandom
缺少,而是如何tr
在OS X的作品而不是瞎搞与enviornment的varialbes,使用perl
代替tr
:
perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo
这具有可跨OS X,Redhat和Ubuntu移植的优势。
(我还删除了到的管道xargs
,替换了witch echo
,以在输出末尾获得换行符。)
binmode ":utf8"
标准,这时您的Perl解决方案就会遇到同样的问题tr
。
首先,您打算将有效字符包含在列表中-
还是将其包含*
在列表中?要tr
包含的参数的序列)-+
表示“以开头)
和结尾的字节范围+
,实际上是)*+
。
其次,而不是从内核的熵池读千字节(并由此标志着整个池不安全的,这将影响需要安全的熵的任何其他进程),只考虑读书一样多的位,你需要:使用head -c...
作为第一个步骤中,然后翻译而不是丢弃不需要的字符。
这个问题的特殊版本使用76个不同的符号,这有点不寻常。大多数人只想要字母数字,所以如果您只对64个符号感到满意,那么使用该base64
实用程序将使熵池的消耗最小化(请注意,24是32的6/8):
head -c24 < /dev/random | base64
您的语言环境的字符编码(可以用来告诉locale charmap
)是每个字符一个多字节。
如今最常见的是UTF-8,其中字符可以编码为1到4个字节。并非所有字节序列都在UTF-8中形成有效字符。UTF-8中的每个非ASCII字符都以一个设置了两个最高位的字节开始,并告诉接下来有多少个设置了最高(但不是第二高)位的字节。
/dev/urandom
包含一个随机字节流。tr
对字符进行音译,因此它需要将这些字节解码为字符。您范围内的那些ASCII字符全部以UTF-8编码为一个字符,但tr
仍需要解码所有字符。例如,还有其他多字节编码,其中某些字符不A
包含0x41字节(的代码A
)。
因为该随机字节流必然包含无效序列(例如,0x80字节本身在UTF-8中无效,因为非ASCII字符必须以大于0xc1的字节开头(0xc0和0xc1不得为UTF- 8个字符)),因此tr
在发生这种情况时返回错误。
您在这里想要的是将字节流视为编码中的每个字符一个字节的字符。无论你选择的是不是在你的范围内,因为所有重要的那些字符(由AZ假设,你的意思是像ABCDEFGHIJKLMNOPQRSTUVWXYZ而不是东西Ý
,Ê
)是便携式的字符集,以便进行编码相同的所有支持系统上的字符集的一部分。
对于这一点,你会设置LC_CTYPE
本地化变量,它是一个决定哪些字符集使用什么之类的东西blank
,alpha
人物类包含。但是,对于AZ范围的定义,您还需要设置LC_COLLATE
变量(决定字符串顺序的变量)。
所述C
又名POSIX
区域是一个保证字符是单字节和AZ是ABCDEFGHIJKLMNOPQRSTUVWXYZ。您可以这样做:
LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
(在此将-
移至末尾,否则)-+
将作为范围A-Z
)
但是请注意,该LC_ALL
变量会覆盖所有其他变量LC_*
和LANG
变量。因此,如果LC_ALL
已经另外定义,则以上内容将无效。因此,您可以简单地执行以下操作:
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'
这将影响其他内容,例如错误消息的语言,但是无论如何,更改LC_CTYPE可能已经是错误消息的问题(例如,无法在C语言环境的字符集中表达俄语或日语错误消息)。
根据手册页,/ dev / random可能足以满足您的需求。也许苹果因为不必要而停止创建/ dev / urandom了?
/dev/random
。
xargs
...