我正在尝试应用 SHA256,然后在 shell 脚本中对字符串进行 Base64 编码。让它与 PHP 一起工作:
php -r 'echo base64_encode(hash("sha256", "asdasd", false));'
.但我正在努力摆脱对 PHP 的依赖。
这行代码在终端中运行良好(使用 shell fish
):
$ echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
X9kkYl9qsWoZzJgHx8UGrhgTSQ5LpnX4Q9WhDguqzbg=
但是当我将它放入 shell 脚本中时,结果有所不同:
$ cat foo.sh
#!/bin/sh
echo -n "asdasd" | shasum -a 256 | cut -d " " -f 1 | xxd -r -p | base64
$ ./foo.sh
IzoDcfWvzNTZi62OfVm7DBfYrU9WiSdNyZIQhb7vZ0w=
我怎样才能让它产生预期的结果?我的猜测是这是因为二进制字符串的处理方式?
答案1
问题是您使用了不同的外壳。该echo
命令是大多数 shell 的内置 shell,并且每个实现的行为都不同。现在,您说您的默认 shell 是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=
上面的内容在命令行和脚本中的工作方式相同,并且应该在您想尝试的任何 shell 中执行此操作。还有一个原因printf
比echo
。