有没有办法将stdin / out而不是文件提供给unix中的程序?

时间:2010-11-03 22:32:02

标签: bash unix

我有一个来自第三方的命令行实用程序(它很大,用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

如果没有我修改第三方应用程序,是否可以这样做?

4 个答案:

答案 0 :(得分:10)

你可以在bash中使用“进程替换”来实现你想要的东西。

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

应该做的伎俩。 <(list)部分是流程替换。

答案 1 :(得分:10)

您应该能够使用/ dev / stdin:

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

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

答案 2 :(得分:2)

如果/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进程从管道读取(好像它是一个普通文件),清空缓冲区就像这样做。

答案 3 :(得分:2)

这并不容易。 / dev / stdin,命名管道和&lt;()进程替换不会被程序以与文件相同的方式访问。特别是在这样的构造中不可能使用fseek(),fsetpos(),因为它的长度不是先验的。

fopen(),getc(),fread()等函数会起作用。因此,对于大多数只是逐行读取输入或逐字符读取的程序,这样做。

如果您的程序在文件中搜索(并且可能会执行其他&#34;更高级的操作),那么您将需要创建一个临时文件。