0

If I had a running process like tail -F watch.txt and I wanted to capture the stdout from this running process and pipe it to another command on stdout how could this be done?

Here's an example of a running process.

$ tail -F watch.txt
foo
bar
baz

Let's say I wanted to capture the stdout and write each of these a new file or process each string with another command. For instance there's this terminal-notifier (mac specific) command that takes a message terminal-notifier --message "$STDOUT_FROM_TAIL".

Is this possible with things that already exist within unix?

2
  • Since it is already running, you might have to redirect the file descriptor of that process elsewhere. Try: ingvar.blog.redpill-linpro.com/2010/07/10/…
    – muru
    Dec 11, 2014 at 23:54
  • If the problem is to call terminal-notifier for each new line that tail -f reports, have a look at xargs
    – Jasper
    Dec 11, 2014 at 23:56

1 Answer 1

1

Assuming you can restart the program and put it in a pipe, you can then pipe it to xargs, with the following caveats:

  • you want to run the command one line at a time (-n 1)
  • you want to put the output inside a parameter (-i)
  • you probably want the message to run as soon as the tail reports it, so you need tail to be line buffered.

Depending on what you have installed:

stdbuf -o 0 tail -f FILE | xargs -i -n 1 terminal-notifier --message "{}"

unbuffer    tail -f FILE | xargs " "

and I saw a tailf version that supported the -l (line-buffered) option.

You can also emulate tail -f in Perl.

And you can replace xargs (even if it's pretty standard and ubiquitous) with a specially crafted for loop in the shell (it's not as simple as it looks, though; it's similar to processing filenames with spaces in a loop).

If you cannot restart the program, you need to intercept its stdout. Here's a Stack Overflow answer about that. Other utilities and scripts such as reredirect are described here; I don't know about their compatibility with MacOS, though.

Further modifications

The output can be parsed normally with utilities such as sed or cut:

unbuffer tail -f FILE | grep animal | sed -e 's/animal (.*) gear/\1/' | xargs ...

This way we would have:

Output by tail                      output by grep        output by sed
correct horse battery staple
animal rhino gear                   animal rhino gear     rhino
llama is animal                     llama is animal       llama is animal
llama peruvian                      
animal ant gearbox                  animal ant gearbox    antbox

(--line-buffered option to grep may be used)

8
  • I can restart the program. However I'm on mac and don't have stdbuf or unbuffer installed. Should I install one of those or is there another alternative caked into OSX? Dec 12, 2014 at 0:56
  • Do you have Perl installed? I can amend the answer tomorrow morning.
    – LSerni
    Dec 12, 2014 at 1:12
  • Just got stdbuf installed but I'm getting xargs: illegal option -- i ideas? Dec 12, 2014 at 2:23
  • I don't have a Mac, but check with xargs -h or --help how to set up a replacement pattern. Could be -R "{}" for example.
    – LSerni
    Dec 12, 2014 at 6:48
  • echo a b c d e f | xargs -I letter -n 1 terminal-notifier -message letter I got this example to work :) Dec 12, 2014 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.