如何避免在 Linux 上创建 tmp 文件?

How to avoid creating tmp-Files on Linux?

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

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

通常我会将其通过管道传递给命令,但 STDIN 已经 "in use"。有什么方法可以将这两个变量传递给命令,而不创建 tmp 文件?

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

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

解决此问题

因为你告诉命令从文件描述符 3 读取,你需要在你 运行 命令时打开它。您可以打开文件描述符 3 以从具有 command --file /dev/fd/3 <some_file 的文件中读取,但如果您这样做,您也可以 运行 command --file some_file。这有用的地方是文件描述符 3 可以来自管道。 shell 中的管道始终将左侧的标准输出连接到右侧的标准输入,但您可以使用 file descritor redirection 移动文件描述符。

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

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

的值

这适用于任何 sh 变体。

bash、ksh 和 zsh 中有一个更简单的语法:process substitution。下面的代码几乎等同于上面的代码:

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

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

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