Michael
Michael

Reputation: 5949

How to redirect a text file output into a pipe?

I am running a Unix tool that takes an option -l log_file. I would like to redirect that into a pipe, something like this:

my_tool -l /dev/tty | grep "Aye, Caramba!"

Unfortunately, when I specify /dev/tty the my_tool's output goes directly to the console window, bypassing grep.

I also tried /dev/stdout, to no avail.

Thus the question: what do I need to specify for the option -l above in order to capture the corresponding output into the pipe?

Upvotes: 2

Views: 226

Answers (4)

dimo414
dimo414

Reputation: 48884

You can use process substitution to create a file handle that pipes any contents written to the handle through a command pipeline.

For example, this should work:

my_tool -l >(grep "Aye, Caramba!" > path/to/store/partial.log)

This passes my_tool a /dev/fd/XXX path which it can write to. Any contents written to that path are piped through grep and then written to the partial.log file.

Functionally this is similar to Kenster's suggestion to use named pipes, but process substitution is often easier to work with and reason about, in my opinion.

Upvotes: 2

Jorge Torres
Jorge Torres

Reputation: 1465

It might be useful to run one process generating the log, and another following the log being created and grepping its output

To do it that way, in one console you could run my_tool, generating the desired log.

my_tool -l /tmp/mylog

Then in a different console you could run:

tail -f -n+0 /tmp/mylog | grep --line-buffered the_pattern_to_match

tail will print the "last" lines of the file passed as argument. -n+0 tells tail to process the full file up to where it has been written. -f tell tail to keep the file open and keep sending whatever arrives to standard output (in this case redirected to the pipe).

Then in grep you will want the --line-buffered so it does not wait for tail to finish before it prints its own output.

I hope this helps.

Upvotes: 0

Jokester
Jokester

Reputation: 5617

Try my_tool -l /dev/stdout | grep

Also as Zach suggested, the command itself may support some other option.

Upvotes: 0

Kenster
Kenster

Reputation: 25458

You could try using a named pipe:

mkfifo pipe
grep "Aye, Caramba!" pipe &
my_tool -l pipe

In this example, grep will open pipe for reading, which will block until another process opens it for writing. When my_tool writes data into the pipe, grep will be able to read the data. Once my_tool closes pipe, grep will get an end-of-file indication and exit.

Upvotes: 2

Related Questions