1

我有一个需要访问文件的程序。这个文件的内容在一个变量中,我想避免创建一个真实的文件。是否可以创建某种虚拟文件?

X='some stuff'
Y='other stuff'
echo $X > some_file
echo "$Y" | command --file some_file -

通常我会将它传递给命令,但 STDIN 已经“使用中”。有没有办法将两个变量都传递给命令,而不创建 tmp 文件?

4

1 回答 1

1

标准输入是文件描述符 0,按照惯例,它用于传递“默认”输入。除了标准输入,大多数命令只允许您通过传递文件名来指定输入。

Linux 和大多数其他现代 unice 都有一个“特殊”文件名,意思是“这个文件描述符上已经打开的任何东西”:. 因此,要从文件描述符 3 而不是某个磁盘文件中读取,请通过. 这适用于大多数命令;此时唯一的障碍是某些命令坚持使用具有特定扩展名的文件名。您通常可以使用符号链接解决此问题。/dev/fd/Ncommandcommand --file /dev/fd/3

由于您告诉命令从文件描述符 3 中读取,因此您需要在运行命令时将其打开。您可以打开文件描述符 3 以从具有 的文件中读取command --file /dev/fd/3 <some_file,但如果这样做,您不妨运行command --file some_file. 这很有用的是文件描述符 3 可以来自管道。shell 中的管道总是将左侧的标准输出连接到右侧的标准输入,但您可以使用文件描述符重定向来移动文件描述符。

echo "$X" | {
  echo "$Y" | command --file /dev/fd/3 -
} 3<&0

在此示例中,整个大括号组的文件描述符 3 从接收$X. 因此,当command从名称传递给 的文件中读取时--file,它会看到 的值X

这适用于任何 sh 变体。

有一种更简单的语法适用于 bash、ksh 和 zsh:进程替换。下面的代码几乎等同于上面的代码:

echo "$Y" | command --file <(echo "$X") -

shell 选择一个空闲的文件描述符并从echo "$X"该描述符创建一个管道,并替换<(…)为正确的./dev/fd/N

在这两种情况下,传递给的文件--file都是管道。因此,这仅在命令与管道一起使用时才有效。某些命令不适用于管道,因为它们不是从头到尾线性地从文件中读取;使用此类命令,您必须使用临时文件。

于 2019-08-09T15:43:13.983 回答