Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prepend to a stream in Bash?

Suppose I have the following command in bash:

one | two

one runs for a long time producing a stream of output and two performs a quick operation on each line of that stream, but two doesn't work at all unless the first value it reads tells it how many values to read per line. one does not output that value, but I know what it is in advance (let's say it's 15). I want to send a 15\n through the pipe before the output of one. I do not want to modify one or two.

My first thought was to do:

echo "$(echo 15; one)" | two

That gives me the correct output, but it doesn't stream through the pipe at all until the command one finishes. I want the output to start streaming right away through the pipe, since it takes a long time to execute (months).

I also tried:

echo 15; one | two

Which, of course, outputs 15, but doesn't send it through the pipe to two.

Is there a way in bash to pass '15\n' through the pipe and then start streaming the output of one through the same pipe?

like image 302
Paul Avatar asked Jun 28 '13 20:06

Paul


People also ask

How to append text to the beginning of a file bash?

To add the text at the beginning of the existing first line, use the -n argument of echo. Note that although Bash or many other shells do not have a limit on the size of a variable, however, the size may be limited based on the environment and system configuration.

How do I append to a variable in bash?

The += Operator in Bash Bash is a widely used shell in Linux, and it supports the '+=' operator to concatenate two variables. As the example above shows, in Bash, we can easily use the += operator to concatenate string variables.


2 Answers

You just need the shell grouping construct:

{ echo 15; one; } | two

The spaces around the braces and the trailing semicolon are required.

To test:

one() { sleep 5; echo done; }
two() { while read line; do date "+%T - $line"; done; }
{ printf "%s\n" 1 2 3; one; } | two
16:29:53 - 1
16:29:53 - 2
16:29:53 - 3
16:29:58 - done
like image 58
glenn jackman Avatar answered Oct 11 '22 15:10

glenn jackman


Use command grouping:

{ echo 15; one; } | two

Done!

like image 45
gniourf_gniourf Avatar answered Oct 11 '22 14:10

gniourf_gniourf