Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

So, I need to write a Bourne-shell script, where my script has to work with the line, that was just echoed to stdout - e.g.:

echo *something* | myscript.sh [parametres...] 

This may be a basic thing, what I might have missed during my studies. I would include my attempts, but they are nowhere near the solution. Anyway, any hint appreciated.

share|improve this question

3 Answers 3

up vote 4 down vote accepted

The key thing to be aware of here is that children inherit the STDIN/STDOUT/STDERR file descriptors of their parent. Meaning if you launch a script with STDIN connected to the STDOUT from another process (a pipe, such as your example), then anything launched by that script will also have it's STDIN connected to that same STDOUT from the other process.

Meaning if you do echo foo | ./myscript.sh where myscript.sh is:

#!/bin/bash
sed -e 's/foo/bar/'

then sed will read from the echo foo and write to STDOUT (which will be connected to your TTY since it wasn't redirected when myscript.sh was launched).
Example:

$ echo foobar | ./myscript.sh
barbar

 

So how you use this depends on what you want to do. If you simply want to capture the input into a variable, you can use the read builtin to do this.
For example:

#!/bin/bash
IFS= read -rd '' foo
echo "foo=<$foo>"

Which results in:

$ echo -e 'hello\nworld' | ./myscript.sh
foo=<hello
world>
share|improve this answer
echo " foo bar " | {
# ...
IFS= read -r line
echo "$line"
}
share|improve this answer

The standard output of the left-hand side of the pipe is connected to the standard input of the right-hand side of the pipe. In your example, the output from echo becomes the input to myscript.sh.

If you want to store the whole output of echo into a variable, you can use a command substitution with cat.

whole_input=$(cat)

This strips off newlines at the end of the input.

You can also use the read builtin if you want to read one line at a time. Note that plain read splits the line into fields and uses backslash continuations; to read one line without additional complications, use IFS= read -r:

IFS= read -r first_line
IFS= read -r second_line
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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