I have a file named my_file.txt whose content is just the string Hello. How could I redirect its content to the command echo?

I know I have the commands less, cat, more... but I need to do it with echo.

I tried this:

$ cat my_file.txt | echo

and also this:

$ echo < my_file.txt

But in both cases it appears only a blank in the stdout, not the content of my_file.txt.

How could I do that?

  • 8
    Why do you insist on using echo? – Kevin Feb 4 '13 at 14:53
  • 8
    @Kevin, presumably eventually he wants to expand the ANSI C escape sequences (\n, b...) in the file, which would be a valid usage of echo (at least a standard echo). Or presumably he wants to understand why it doesn't work that way. In any case, no reason to downvote IMO. – Stéphane Chazelas Apr 2 '13 at 6:38
  • 3
    I came here because I was curious about why it doesn't work when I do echo < file.txt. Seems a reasonable question to have at SE, the answer was very helpful. +1 from me. – neuronet Jun 16 '16 at 15:01

You can redirect all you want to echo but it won't do anything with it. echo doesn't read its standard input. All it does is write to standard output its arguments separated by a space character and terminated by a newline character (and with some echo implementations with some escape sequences in them expanded and/or arguments starting with - possibly treated as options).

If you want echo to display the content of a file, you have to pass that content as an argument to echo. Something like:

echo "$(cat my_file.txt)"

Note that $(...) strips the trailing newline characters from the output of that cat command, and echo adds one back.

Also note that except with zsh, you can't pass NUL characters in the arguments of a command, so that above will typically not work with binary files. yash will also remove bytes that don't form part of valid characters.

If the reason for wanting to do that is because you want echo to expand the \n, \b, \0351... escape sequences in the file (as UNIX conformant echo implementations do, but not all), then you'd rather use printf instead:

printf '%b\n' "$(cat my_file.txt)"

Contrary to echo, that one is portable and won't have problems if the content of the file starts with -.

As an alternative to $(cat file), with ksh, zsh and bash, one can also do: $(<file). That's a special operator whereby the shell as opposed to cat reads the content of the file to make up the expansion. It still strips the trailing newlines and chokes on NUL bytes except in zsh. In bash, that still forks an extra process. Also note that one difference is that you won't get any error if trying to read a file of type directory that way. Also, while $(< file) is special, $(< file; other command) is not (in zsh, when not emulating other shell, that would still expand the content of the file, by running the implicit $READNULLCMD command (typically a pager)).

  • 3
    In both bash and zsh you can skip the cat and just have the shell read it in directly: echo "$(<my_file.txt)". – Kevin Feb 4 '13 at 14:52
  • 1
    Yes, with ksh, zsh and bash you can use $(<filename). – Dimitre Radoulov Feb 4 '13 at 15:25
  • Thank you so much, that's what I needed and it worked! :-) – danielmbcn Feb 4 '13 at 15:36
  • @Kevin, Dimitre, added now. – Stéphane Chazelas May 8 '17 at 7:58

Adding to other answers, you can also try input redirection instead of cat

echo $(<my_file.txt)


echo `<my_file.txt`

$() and `` perform the same thing, they run commands inside of their scope and give the output to the shell as if it was given as an input by the user. The only difference between these two is that $() can be recursive and `` can't be recursive.


As it was said,

If you want echo to display the content of a file, you have to pass that content as an argument to echo

For instance, you can do it like this with xargs (considering that you need to enable interpretation of backslash escapes):

$ cat my_file.txt | xargs echo -e

Or simply what you've asked (whithout interpretation of escapes sequences):

$ cat my_file.txt | xargs echo
  • Note however that when using xargs echo (same as xargs btw as echo is the default command), it's the echo command from the file system that will be run, not the shell's builtin echo command. Also note that xargs expects its input in a very specific format (where blanks, newlines, quotes, backslashes have special meaning). cat doesn't make much sense here as there's only one file to concatenate (same as < file.txt xargs echo. Note that Unix compliant echos do backslash escape expansion by default and output -e upon echo -e. – Stéphane Chazelas May 8 '17 at 8:39

Simple answer: you can't. echo (be it shell built-in or regular binary) doesn't process its standard input - it is one way only.

  • Question is, why would you actually want to do this? – peterph Feb 4 '13 at 19:14

In bash, also the following should work:

echo `cat my_file.txt`

The part in backticks is replaced by the output of that command, i.e. in this case replaced by the file contents.

  • True, backticks work like $( . . . ). People who use $() usually prefer them because you can nest them. This question is old, though, it's much more satisfying to answer questions that are not already answered! – Law29 Jul 1 '16 at 9:12
  • Not quite. There is a subtle difference. When the back-tick form is used, a backslash retains its literal meaning except when followed by $, `, or \. The first back-tick not preceded by a backslash terminates the command. When using the $(,,,) form, all characters between the parentheses make up the command. – fpmurphy Jul 1 '16 at 11:29
  • As that command substitution is not quoted, the split+glob operator would be applied to it. For instance if my_file.txt contains *, that would print the list of file names in the current directory. – Stéphane Chazelas May 8 '17 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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