Reputation: 81
All I want to do is just redirect the executed command's stdout to a pipe. An example will explain it better than I do.
$ echo "Hello world" | cowsay
outputs "Hello world" in cowsay, i want to preprocess terminal's / bash stdout to pass through cowsay
$ echo "Hello world"
this should output the same as the first command.
Thanks in advance.
Upvotes: 6
Views: 1014
Reputation: 123400
You can use process substitution:
#!/bin/bash
exec > >(cowsay)
echo "Hello world"
However, there are caveats. If you start anything in the background, the cow will wait for it to finish:
#!/bin/bash
exec > >(cowsay)
echo "Hello world"
sleep 30 & # Runs in the background
exit # Script exits immediately but no cow appears
In this case, the script will exit with no output. 30 seconds later, when sleep
exits, the cow suddenly shows up.
You can fix this by telling the programs to write somewhere else, so that the cow doesn't have to wait for them:
#!/bin/bash
exec > >(cowsay)
echo "Hello world"
sleep 30 > /dev/null & # Runs in the background and doesn't keep the cow waiting
exit # Script exits and the cow appears immediately.
If you don't start anything in the background, one of your tools or programs do. To find which ones, redirect or comment them out one by one until cows appear.
Upvotes: 4
Reputation: 780673
You can use a named pipe:
mkfifo /tmp/cowsay_pipe
cowsay < /tmp/cowsay_pipe &
exec > /tmp/cowsay_pipe # Redirect all future output to the pipe
echo "Hello world"
Upvotes: 3