SHA256を適用してから、Base64でシェルスクリプト内の文字列をエンコードしようとしています。 PHPで動作するようになりました:php -r 'echo base64_encode(hash("sha256", "asdasd", false));'
。しかし、私はPHP依存関係を取り除こうとしています。
ターミナルでうまく機能するこの行を取得しました(fish
シェルを使用):
$ echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
しかし、それをシェルスクリプト内に置くと、結果は異なります。
$ cat foo.sh
#!/bin/sh
echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
$ ./foo.sh
IzoDcfWvzNTZi62OfVm7DBfYrU9WiSdNyZIQhb7vZ0w=
どうすれば期待どおりの結果が得られるようにできますか?私の推測では、バイナリ文字列の処理方法が原因だと思いますか?
問題は、異なるシェルを使用していることです。 echo
コマンドは、ほとんどのシェルに組み込まれているシェルであり、実装ごとに動作が異なります。ここで、デフォルトのシェルはfish
であると言いました。したがって、このコマンドを実行すると、次のようになります。
~> echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
上記の出力が得られます。これは、echo
のfish
が-n
をサポートしているためです。どうやら、あなたのシステムでは、/bin/sh
はecho
が-n
をサポートしていないシェルです。 echo
が-n
を理解しない場合、実際に印刷されるのは-n asdasd\n
です。説明のために、printf
を使用して正確に次のことを出力してみましょう。
$ printf -- "-n asdasd\n"
-n asdasd
さて、それをあなたのパイプラインに通すと:
$ printf -- "-n asdasd\n" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
IzoDcfWvzNTZi62OfVm7DBfYrU9WiSdNyZIQhb7vZ0w=
これが、スクリプトから得られる出力です。つまり、echo -n "asdasd"
が実際に-n
との末尾の改行を出力しているということです。簡単な解決策は、printf
の代わりにecho
を使用することです。
$ printf "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
上記はコマンドラインとスクリプトで同じように機能し、試してみたいシェルでも同じように機能するはずです。 printf
がecho
よりも優れているもう1つの理由。