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?
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.
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.
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.