Search code examples
linuxbashechostdoutstdin

Echo Stdin confusion


I have created two files namely file1.txt and file2.txt. When I write

echo < file1.txt

It returns an empty line. But cat < file1.txt returns the contents of the file1.txt.

Since echo prints whatever is sent to it, why is echo not printing the contents of the file1.txt?


Solution

  • This is the duplicate and has been resolved: https://unix.stackexchange.com/questions/63658/redirecting-the-content-of-a-file-to-the-command-echo

    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 -.