【问题标题】:Is there any way to supply stdin/out instead of a file to a program in unix?有什么方法可以向 unix 中的程序提供标准输入/输出而不是文件?
【发布时间】:2015-02-03 01:34:26
【问题描述】:

我有一个来自第三方的命令行实用程序(它很大并且用 Java 编写),我一直在使用它来帮助我处理一些数据。此实用程序需要行分隔文件中的信息,然后将处理后的数据输出到 STDOUT。

在我的测试阶段,我可以编写一些 Perl 来创建一个包含要处理的信息的文件,然后将该文件发送到这个第三方实用程序,但是当我即将将此代码投入生产时,我'我真的更喜欢直接将数据通过管道传输到该实用程序,而不是首先将该数据写入文件,因为这样可以节省我将不需要的信息写入磁盘的开销。有没有办法在unix中做到这一点?

目前我调用该实用程序如下:

bin/someapp do-action --option1 some_value --input some_file

我想做这样的事情:

bin/someapp do-action --option1 some_value --input $piped_in_data

如果我不修改第三方应用程序,这样的事情可能吗?

【问题讨论】:

  • StackExchange 上有更全面的答案,请参阅 unix.stackexchange.com/questions/16990/…>。

标签: bash unix


【解决方案1】:

你应该可以使用 /dev/stdin:

bin/someapp do-action --option1 some_value --input /dev/stdin

(请注意,在某些系统上,/dev/stdin 是一个符号链接;如果您的 Java 程序无法处理此问题,您可能不得不使用 /dev/fd/0 或类似的东西。)

【讨论】:

  • 那么我什么时候将数据发送到标准输入呢?我打电话后它会等它吗?还是我会在手前立即做?这究竟是如何工作的?
  • 在普通管道中使用:generate_data.pl | bin/someapp do-action --option1 some_value --input /dev/stdin
  • 太棒了。这正是我想要的。
  • 原来这实际上不起作用。运行它时,我得到:线程“主”java.io.FileNotFoundException 中的异常:/dev/stdin(没有这样的设备或地址)。该死。有什么想法吗?
  • 查看您系统上的 /dev/stdin(即ls -l /dev/stdin)。它真的存在吗?它是设备文件还是符号链接或什么?如果是符号链接,请尝试使用它指向的实际设备文件。
【解决方案2】:

您可以在 bash 中使用“进程替换”来实现您想要的效果。

bin/someapp do-action --option1 some_value --input <(generate_input.sh)

应该可以解决问题。 &lt;(list) 部分是进程替换。

【讨论】:

  • 甜蜜!有没有办法在那里使用 perl 脚本?为了测试,我尝试了: echo
  • 试试:cat -
  • 或者只是cat &lt;(perl whatever)。 echo 不知道读取文件,但 cat 知道。
【解决方案3】:

如果/dev/stdin 技术由于某种原因不适合,另一种方法是使用“命名管道”。

如果你这样做

% mkfifo /path/to/file

然后这将创建一个具有该名称的文件系统对象,它可以充当两个进程之间的管道。这与普通管道所发生的情况相同,只是进程可以像引用普通文件一样引用管道。例如:

% mkfifo /tmp/my-fifo
% grep alias ~/.bashrc >/tmp/my-fifo &
[1] 70134
% sed 's/alias/wibble/' /tmp/my-fifo
wibble ls='ls -F'
....
[1]  + done       grep alias ~/.bashrc > /tmp/my-fifo
% 

这里,grep 命令正在写入 FIFO,就像它是一个普通文件一样,当命名管道的缓冲区填满时它会阻塞。 sed 进程从管道中读取数据(就像它是一个普通文件一样),同时清空缓冲区。

【讨论】:

    【解决方案4】:

    这并不容易。 /dev/stdin、命名管道和

    一些函数,如 fopen()、getc()、fread() 等仍然可以工作。因此,对于大多数仅逐行或逐字符读取输入的程序来说,这将是可行的。

    如果您的程序在文件中查找(并且可能会执行其他“更高级”的操作),那么不幸的是,您需要创建一个临时文件。

    【讨论】:

      猜你喜欢
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 2019-12-05
      • 1970-01-01
      • 2014-02-10
      • 2014-05-27
      • 1970-01-01
      相关资源
      最近更新 更多