Bash 进程替换可以用作参数扩展的一部分吗?

Bash 进程替换可以用作参数扩展的一部分吗?

我熟悉使用规范方式进行流程替换,例如

diff <(ls /folder1) <(ls /folder2)

但是,当进程需要一个参数时,可以使用它吗?不是只是表达式的路径?例如

curl -XPOST https://host:1234/upload -F data=@$(echo <(head -c1M /dev/urandom))

这是行不通的,因为内部替换存在于子 shell 进程中,而不是外部进程中;尽管如此,这实际上是我想要实现的目标。

答案1

当您使用该<(cmd)语法时,通常会发生的情况是“cmd”使用连接到临时文件描述符的 stdout 运行,并且返回该描述符的文件名,因此它可以用作参数

例如

ksh$ echo <(echo hello)
/dev/fd/4

bash$ echo <(echo hello)
/dev/fd/63

现在,该/dev/fd/##条目仅在调用的 shell 范围内有效,<(..)因为/dev/fd是 的符号链接/dev/self/fd

这意味着在您的示例中,data=@$(echo <(head -c1M /dev/urandom))if 将被解析为就像您已输入一样,data=@/dev/fd/63但这不起作用,因为运行该curl命令的 shell 不是进行进程替换的 shell。

现在<(...)可以包含在其他条目中,只要您不传递临时文件名,它就可以工作

例如,这行不通

$ cat <(echo <(echo hello))
/dev/fd/63

但是这个将要工作

$ cat <(cat <(echo hello))
hello

但是,在您的版本中,您有不必要的间接级别,并且应该能够简单地执行以下操作

data=@<(head -c1M /dev/urandom)

相关内容