临时数据的伪文件

临时数据的伪文件

我经常想将相对较短的字符串数据(尽管可能是几行)提供给命令行程序,这些程序仅以重复的方式接受来自文件(例如 wdiff)的输入。当然,我可以创建一个或多个临时文件,将字符串保存在那里,然后使用文件名作为参数运行命令。但在我看来,如果数据实际写入磁盘,这个过程的效率会非常低,而且如果我多次重复这个过程,例如,如果我想输入单行长文本,它可能会对磁盘造成不必要的伤害。文件到 wdiff。是否有推荐的方法来规避此问题,例如使用管道等伪文件临时存储数据,而不实际将其写入磁盘(或仅在超过临界长度时才写入)。请注意, wdiff 需要两个参数,据我了解,不可能通过执行类似wdiff <"text".

答案1

在 Bash 中,您可以使用command1 <( command0 )重定向语法,该语法会重定向command0的 stdout 并将其传递给command1将文件名作为命令行参数的 a。这就是所谓的流程替代

一些采用文件名命令行参数的程序实际上需要一个真正的随机访问文件,因此该技术不适用于这些程序。但是,它可以很好地使用wdiff

user@host:/path$ wdiff <( echo hello; echo hello1 ) <( echo hello; echo hello2 )
hello
[-hello1-]
{+hello2+}

在后台,这会创建一个 FIFO,将内部命令通过管道传输<( )到 FIFO,并将 FIFO 的文件描述符作为参数传递。要查看发生了什么,请尝试使用它来echo打印参数而不对其执行任何操作:

user@host:/path$ echo <( echo hello )
/dev/fd/63

创建命名管道更加灵活(如果您想使用多个进程编写复杂的重定向逻辑),但对于许多用途来说这已经足够了,并且显然更易于使用。

还有>( )当您想将其用作输出时的语法,例如

$ someprogram --logfile >( gzip > out.log.gz )

也可以看看bash 手册页“进程替换”部分Bash 重定向备忘单以获得相关技术。

答案2

用一个命名管道。举例来说:

mkfifo fifo
echo -e "hello world\nnext line\nline 3" > fifo

告诉-eecho 正确解释换行符 ( \n)。这将阻塞,即您的 shell 将挂起,直到有东西从管道读取数据。

在同一目录中的某处打开另一个 shell:

cat fifo

您将读取回显,这将释放另一个 shell。尽管管道作为文件节点存在于磁盘上,但通过它的数据却不是;这一切都发生在记忆中。您可以设置&回声背景 ( )。

该管道有一个 64k 缓冲区(在 Linux 上),并且像套接字一样,在满时会阻塞写入器,因此只要您不过早终止写入器,就不会丢失数据。

答案3

wdiff 是一种特殊情况,因为它需要 2 个文件名参数,但对于仅需要 1 个参数并且顽固地拒绝接受除文件名参数之外的任何内容的所有命令,有 2 个选项:

  • 文件名“-”(即减号)大约有 1/2 的时间起作用。这似乎取决于所讨论的命令以及命令的开发人员是否捕获该情况并按预期处理它。例如

    $> ls |猫 -

  • Linux 中存在一个名为 /dev/stdin 的伪文件,如果命令绝对需要文件名,则可以使用它。这更有可能起作用,因为它不需要命令进行任何特殊的文件名处理。如果 fifo 有效,或者 bash流程替代方法有效,那么这也应该有效,并且不是特定于 shell 的。例如

    $> ls |猫 /dev/stdin

相关内容