同僚は、次のコマンドで任意のキーを作成することを提案しました。
tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
エラーが発生します。
tr:無効なバイトシーケンス
私のシステムにないと思います/dev/urandom
。このファイルをインストールする方法を見つけるためにインターネットを検索しようとしましたが、空の結果が出ました。私はそれを試しましたが、locate urandom
何も得られませんでした。 (実際にマニュアルページを見つけましたが役に立ちませんでした)
urandom
Mac OSXシステムでどのように使用しますか? (ライオン)
答え1
/dev/urandom
あなたが受け取ったエラーメッセージによると、これは問題ではないようです。その場合、同様のエラーが発生すると予想されますno such file or directory
。
あなたが受け取ったエラーメッセージを検索したところ、次のメッセージが見つかりました。これはあなたの問題に関連しているようです。nerdbynature.de 2010-04-11 tr-Illegal-byte-sequence (Web アーカイブの 2019-09 スナップショット)
tr
デフォルトでは、コマンドの前に追加LC_CTYPE=C
(または説明を参照)してロケールを指定します。LC_ALL=C
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
答え2
tr
入力をUTF-8でエンコードされたテキストとして解釈しようとしています。したがって、最初のバイトシーケンスが有効なUTF-8ではないというメッセージを表示して中断します。プレフィックスを付けるか、tr
変数を環境にエクスポートすると、ローカル文字セットのアイデアはすべてが不透明バイトのシーケンスであるC標準に変更されます。LC_ALL=C
LC_CTYPE=C
tr
しかし、\)-+
命令の順序は意図的なものですか?これには、*
すでに含まれているが-
必要に応じて含まれていないコンテンツも含まれます。次のように書くことをお勧めします。
LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom
答え3
他の人が指摘したように、問題は欠けているのではなく、OS Xで動作するようにする/dev/urandom
方法です。tr
環境変数を使用しないでください。代わりにperl
次を使用してくださいtr
。
perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo
利点は、OS X、Redhat、およびUbuntuで移植可能であることです。
(またパイプを外しxargs
て魔女を交換して出力のecho
末尾に改行文字を得ました。)
答え4
ロケールの文字エンコーディング(話すために使用できますlocale charmap
)は、文字ごとに1マルチバイトです。
今日最も一般的なのはUTF-8で、文字を1〜4バイトにエンコードできます。すべてのバイトシーケンスがUTF-8で有効な文字を形成するわけではありません。 UTF-8の各非ASCII文字は、最も高い2ビットが設定されたバイトで始まり、その後に最も高いビット(2番目に高いビットではない)が設定されたバイト数が続きます。
/dev/urandom
ランダムバイトストリームを含みます。tr
文字を音訳するので、これらのバイトを文字としてデコードする必要があります。その範囲のASCII文字は1文字からUTF-8にエンコードされますが、tr
すべての文字はまだデコードする必要があります。たとえば、一部の文字にA
0x41バイト(のコード)が含まれていない他のマルチバイトエンコーディングがありますA
。
このランダムバイトストリームには無効なシーケンスが含まれている必要があるためです(たとえば、非ASCII文字は0xc1より大きいバイトで始まる必要があるため、0x80バイト自体はUTF-8では無効です(0xc0と0xc1は非UTF-8には存在しません)、tr
この場合はエラーが返されます。
ここで望むのは、バイトストリームを1文字あたり1バイトのエンコーディングで文字として扱うことです。範囲内のすべての文字(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ロケールの文字セットで表現できません) 。