我熟悉使用规范方式进行流程替换,例如
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)