OSXで/ dev / urandomからtrが読み取れないのはなぜですか?


35

同僚は、次のコマンドを使用してランダムキーを作成することを提案しました。

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

それは私にエラーを与えました:

tr:不正なバイトシーケンス

私は/dev/urandom自分のシステムに持っていないことを心配しています。このファイルのインストール方法を把握するためにグーグル検索を試みましたが、空っぽになりました。私locate urandomも試してみて、空になりました。(まあ実際には、それはマニュアルページを見つけましたが、それは助けにはなりません)

urandomMac OSXシステムで利用できるようにするにはどうすればよいですか?(ライオン)


3
xargs...の興味深い使用
-sendmoreinfo

回答:


49

表示されるエラーメッセージに基づいて、/ dev / urandomが問題だとは思わない。もしそうなら、「no such file or directory」のようなエラーを期待します。

私はあなたが得たエラーメッセージを検索し、これを見つけました。これはあなたの問題に関連しているようです: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ですか?それらは、実際のファイルシステム上に存在しない特別な魔法の「ファイル」ですか?(リンク腐敗の軽減に役立つ編集も提案しました)
カークウォル

1
私は信じてlocate直接あなたのファイルシステムを検索しませんが、むしろ、事前に構築されたデータベースを使用してクエリを検索します。このデータベースは、ほとんどの場合、/ dev /およびその他の「特別な」ファイルシステムを無視するように構成されています。
lk-

十分に公平ですが、を直接見ると表示されません/dev。図を移動します。しかし、助けてくれてありがとう。
カークウォル

1
10.9では動作しないようです。それでも同じエラーメッセージで失敗します。LC_ALL=Cトリックカントーを行います。
エリックアリク

1
現在、情報が含まれていない最新のブログページを指しているため、nerdbynature.de / s9y / 2010/04/11 / tr-Illegal-byte-sequenceへのリンクを変更してtrください。
ジェローンヴィルトプルイマーズ

11

あなたのtrUTF-8エンコーディングにテキストとしてその入力を解釈しようとする試み。したがって、有効なUTF-8ではない最初のバイトシーケンスで文句を言い、中止します。またはで接頭辞をtr付けてその変数をの環境にエクスポートし、ローカル文字セットの考え方をC標準に変更します。つまり、すべてが単なる不透明なバイトのシーケンスです。LC_ALL=CLC_CTYPE=Ctr

ところで、\)-+コマンドのシーケンスは意図的ですか?これには*既に含まれ-ているものも含まれますが、意図したとおりには含まれません。代わりに次のいずれかを記述する方が適切です。

LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom

6

他の人が示されてきたように、あなたの問題はないが/dev/urandom不足しているのではなく、どのようにtrする代わりに環境をいじりのOS X上の作品は、使用をvarialbes perlの代わりにtr

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

これには、OS X、Redhat、Ubuntu間で移植できるという利点があります。

(出力の最後に改行を取得するために、xargswitchに代わるパイプも削除しましたecho。)


遅かれ早かれ、Perlがbinmode ":utf8"標準化することを期待してtrいます。その時点で、Perlソリューションには同じ問題が発生します。
マーク

コードサンプルにbinmode(STDIN、 ":bytes")を追加して、Markの懸念に対処しました。
トレントン

2

最初に、有効な文字のリストを含める-*、リストに含めるつもりでしたか?パラメータは、tr配列を含む)-+「バイト範囲で開始することを意味)し、で終わる+実際には、)*+

第二に、カーネルのエントロピープールから数キロバイトを読み取るのではなく(したがって、プール全体を安全でないとしてマークし、安全なエントロピーを必要とする他のプロセスに影響を与えます)、必要なビットだけを読み取ることを検討してください:最初のステップhead -c...として使用し、不要な文字を破棄するのではなく翻訳します。

この特定のバージョンの問題は、76個の異なるシンボルを使用するという点で少し珍しいです。ほとんどの場合は英数字のみが必要なので、64個のシンボルだけで十分であれば、base64ユーティリティを使用するとエントロピープールの消費が最小限に抑えられます(24は32の6/8であることに注意してください)。

head -c24 < /dev/random | base64

1

ロケールの文字エンコード(でわかるlocale charmap)は、文字ごとにマルチバイトです。

最も一般的なのは、文字を1〜4バイトでエンコードできるUTF-8です。すべてのバイトシーケンスがUTF-8で有効な文字を形成するわけではありません。UTF-8のすべての非ASCII文字は、2つの最上位ビットが設定された1バイトで始まり、最上位(2番目に上位ではない)ビットセットが続くバイト数を示します。

/dev/urandomバイトのランダムストリームが含まれます。tr文字を音訳するため、これらのバイトを文字としてデコードする必要があります。範囲内のASCII文字はすべてUTF-8で1文字にエンコードされますが、trそれでもすべての文字をデコードする必要があります。たとえばA、0x41バイト(のコードA)以外の文字が含まれる他のマルチバイトエンコーディングがあります。

バイトのランダムストリームは無効なシーケンスを含むようにバインドされているため(たとえば、非ASCII文字は0xc1より大きいバイトで始まる必要があるため、0x80バイト自体はUTF-8では無効です(0xc0および0xc1はUTF- 8文字))、それtrが発生するとエラーを返します。

ここで必要なのは、バイトストリームが文字ごとに1バイトのエンコーディングの文字として考えられることです。どちらを選択すること(AZによって仮定して、あなたはABCDEFGHIJKLMNOPQRSTUVWXYZを意味していないようなものは、あなたの範囲内のすべてのものを文字として重要ではありませんÝÊ)ので、あなたのシステムでサポートされているすべての文字セットで同じことをエンコードするポータブル文字セットの一部です。

そのために、LC_CTYPEローカライズ変数を設定します。これは、使用される文字セットとblankalpha文字クラスに含まれるものなどを決定する変数です。ただし、AZの範囲を定義するには、LC_COLLATE変数(文字列の順序を決定する変数)も設定する必要があります。

C別名POSIXロケールは1保証の文字があることを、シングルバイトで、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ロケールの文字セットでロシア語または日本語のエラーメッセージを表現する方法はありません)。


0

マニュアルページによると、おそらく/ dev / randomで十分でしょう。おそらくAppleは/ dev / urandomを作成するのをやめたのは、それが不要だからでしょうか?


/dev/randomどちらも持っていません。
カークWoll

MacOSXには/ dev / randomと/ dev / urandomの両方が必要です。おそらくAppleはこれらの特別なファイルをもう含んでいないのでしょうか?それとも、XCodeをインストールした場合にのみ存在するのでしょうか?
jsbillings

1
FWIW、両方のデバイスがLionにアップグレードされたLion Lionワークステーションに存在します。Lionにも存在していたと思います。ノードも異なります(13,0対13,1)
mrb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.