为什么不能从 OSX 上的 /dev/urandom 读取 tr?

Kir*_*oll 50 osx random tr

一位同事建议通过以下命令创建一个随机密钥:

tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
Run Code Online (Sandbox Code Playgroud)

它给了我错误:

tr:非法字节序列

我担心/dev/urandom我的系统上没有。我试着用谷歌搜索找出如何安装这个文件,但我发现是空的。我试过了locate urandom,结果也是空的。(实际上,它找到了手册页,但这无济于事)

如何urandom在我的 Mac OSX 系统上使用?(狮子)

lk-*_*lk- 64

根据您收到的错误消息,我认为 /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
Run Code Online (Sandbox Code Playgroud)

  • 似乎不适用于 10.9;仍然失败并显示相同的错误消息。`LC_ALL=C` 可以解决这个问题。 (2认同)

MvG*_*MvG 14

tr尝试将其输入解释为 UTF-8 编码的文本。所以它会抱怨并中止第一个无效的 UTF-8 字节序列。trLC_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
Run Code Online (Sandbox Code Playgroud)


Tre*_*ton 8

正如其他人所指出的,您的问题不是/dev/urandom缺少,而是tr在 OS X 上的工作方式。而不是搞乱环境变量,使用perl代替tr

perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo
Run Code Online (Sandbox Code Playgroud)

这具有跨 OS X、Redhat 和 Ubuntu 可移植的优势。

(我还移除了到 的管道xargs,替换了女巫echo,以在输出的末尾获得换行符。)

  • 抱歉,但我有点不明白,为什么对 perl 的依赖比仅仅在命令中添加“LC_ALL=C”前缀更可取。 (3认同)