I have a shell script that takes input from another shell script. The stream gets piped in on stdin.

I need to capture all the bytes of the stdin stream to a single variable in the shell script. Then, perform some operations on it, and send it back out over stdout.

The problem I have is that sometimes there is a trailing newline character in the input file, but sometimes there is not. If there is not, then I do not want to add one. If there is a trailing newline, however, I want to preserve that.

The problem is that no matter what I try, the system either always outputs WITHOUT a trailing newline (as in the case of printf) or it always outputs WITH a newline (as in the case of echo).

Please tell me what is the name of a process (not echo or printf) that simply takes a variable and streams it out, verbatim, byte for byte, over stdout. I have tried all possible options for printf and none of them works to preserve trailing newlines.


  • I believe that you asked the right question when you asked How do I capture stdin to a variable without stripping any trailing newlines? I believe, as you pointed out in that other question, that, if you read stdin and save it into a shell variable, any trailing newline gets stripped at that point. So there’s no way any command can distinguish between the two cases after that. … … … … P.S. Please don’t post nearly-identical questions on multiple Stack Exchange sites (e.g., Super User and U&L) simultaneously. Sep 9, 2014 at 21:17

2 Answers 2


echo -e "$var" will output trailing newlines. Perhaps you forgot the quotes? Always show what you've tried when asking such questions.


The final solution that I used in my code is as follows:

function filter() {
    #do lots of sed operations
    #see https://github.com/gistya/expandr for full code

GIT_INPUT=`cat; echo x`
FILTERED_OUTPUT=$(printf '%s' "$GIT_INPUT" | filter)
printf '%s' "$FILTERED_OUTPUT"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .