在zsh中工作的进程替代,在bash中却不起作用。

huangapple go评论79阅读模式
英文:

Process substitution working in zsh but not is bash

问题

我正在尝试使用以下命令使用证书对一些内容进行签名,该命令使用进程替换将证书内容传递给openssl(因为它要求要么是文件,要么是uri):

echo "something to sign" \
| openssl dgst -binary -sha256 -sign <(echo "certificate to sign with")

这在zsh中运行得很顺利,但当我尝试通过bash运行时,出现错误:

Could not read private key from /dev/fd/63

我在这里做错了什么?

英文:

I'm attempting to sign some content using a certificate with the following command which uses process substitution to deliver the certificate content to openssl (since it requires either a file or uri):

echo &quot;something to sign&quot; \
| openssl dgst -binary -sha256 -sign &lt;(echo &quot;certificate to sign with&quot;)

This runs flawlessly in zsh but when I try to run this via bash I get an error:

Could not read private key from /dev/fd/63

What am I doing wrong here?

答案1

得分: 3

似乎 openssl 不喜欢从命名管道读取。命名管道可用于实现进程替代,类似于不支持 fseek() 的FIFO。

更多信息请查看这里:
https://unix.stackexchange.com/questions/164107/why-does-bash-process-substitution-not-work-with-some-commands

在我的Linux系统上,bash和zsh都无法使用Could not read private key from /dev/fd/63Could not read private key from /proc/self/fd/12。但也许zsh在您的机器上以不同的方式实现了进程替代。

man zshexpn 的"进程替代"部分还有更多关于 &lt;() 的潜在陷阱的信息。它还说 =() 使用临时文件而不是命名管道,所以它可以与需要寻找的程序一起使用。但是Bash没有 =()

英文:

It seems that openssl doesn't like to read from a named pipe. Named pipes can be used for implementing process substitution and operate like a FIFO that doesn't support fseek().

More info here:
https://unix.stackexchange.com/questions/164107/why-does-bash-process-substitution-not-work-with-some-commands

On my Linux system, both bash and zsh fail with Could not read private key from /dev/fd/63, and Could not read private key from /proc/self/fd/12, respectively. But perhaps zsh implements process substitution another way on your machine.

The "Process Substitution" section of man zshexpn has more to say about the possible pitfalls of &lt;(). It also says that =() uses a temporary file instead of a named pipe, so it will work with programs that want to seek. But Bash does not have =().

答案2

得分: 1

结果表明,这一切都是因为凭据有效载荷中的换行符`\n`序列以及在使用`bash`时需要打开反斜杠转义解释的`echo`
```shell
echo &quot;something to sign&quot; \
| openssl dgst -binary -sha256 -sign &lt;(echo -e &quot;certificate to sign with&quot;)

在使用zsh时,反斜杠似乎会自动解释,使我相信问题出在进程替代,而不是凭据的内容。

我觉得没有早点意识到这一点有些愚蠢,但我希望这会帮到将来也会在困境中迷失的某人。


<details>
<summary>英文:</summary>

It turns out this was all due to new line `\n` sequences in the credentials payload and `echo` requiring interpretation of backslash escapes to be turned on when using `bash`.

```shell
echo &quot;something to sign&quot; \
| openssl dgst -binary -sha256 -sign &lt;(echo -e &quot;certificate to sign with&quot;)

When using zsh the backslashes are seemingly interpreted automatically making me believe the issue was with the process substitution but not the contents of the credentials.

It feels silly to not have realized this sooner, but I hope this will help someone in the future also gets lost in the weeds.

huangapple
  • 本文由 发表于 2023年7月14日 00:41:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76681633.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定