7

For example, echo:

[aesteban@localhost ~]$ cat tmp.txt 
Angel
[aesteban@localhost ~]$ echo < tmp.txt

[aesteban@localhost ~]$

As you can see, the output is just a blank line. According to my readings some commands are able to take input redirection, eg mail:

[aesteban@localhost ~]$ mail [email protected] < tmp.txt 

So does input redirection only apply for interactive commands (the ones able to wait for input) ? How do determine if a command is interactive (aside from trying)?

0

3 Answers 3

5

Why some commands don't take input redirection?

The short answer: because they weren't programmed to.

For a program to read from stdin (which is the stream that the shell connects to the file specified after <) is not automatic. It needs to be coded by the programmer. For that matter, reading from files given on the command line is also not automatic. That is, the contents of those files, whether given by redirection or specified by name, do not magically appear inside the program's variables without extra coding.

If a program was never coded to read from a stream, it doesn't matter whether you put a redirection - it will simply not read from it. By its POSIX specification (http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html), echo is not required to read from stdin, and only examines its command-line arguments (and some environment variables). To find out for other programs, you can read the source code, the documentation, or simply try it out as you said :-)

To answer your last question: you cannot really say a command is interactive. You can determine whether the input stream it's reading from is connected to a terminal (as opposed to, for instance, a plain file). There are examples in many languages on http://rosettacode.org/wiki/Check_input_device_is_a_terminal. You could conceive a mailing program that uses this feature to determine if it's being used interactively (accepting keyboard commands to read mail), or non-interactively (say, to read a mail message from a file). I am not sure how mail does it. (Note that mail behaves differently when called with or without command-line arguments!)

2

Most commands that read the content of a file (or files) whose name(s) are specified on the command line will read from standard input if no files are specified on the command line.  Some will also read from standard input if a filename of - is specified on the command line; e.g.,

cat file1 - file2

will read from file1, then standard input, and then file2.  But, if a command doesn't normally read the contents of file(s) whose name(s) are specified on the command line, then it probably won't do anything with standard input, either.  echo never reads from files.

Of course, there are various exceptions:

  • The tr command always reads from standard input, and does not accept filename(s) on the command line.
  • If bc is invoked with filename argument(s), it reads them, and then also reads standard input, unless one of the file(s) has a halt or quit command.
  • Compilers (e.g., the C compiler, which may be called cc or gcc) tend to require (or at least strongly prefer) filename(s) on the command line.  cc will fail if invoked with no filenames on the command line.  cc - will read the standard input only if certain options are specified.
  • It doesn't make sense to invoke cmp or diff with fewer than two sources of input.  They will fail if invoked with no filenames on the command line.  Both of them honor the convention that an argument of - designates the standard input.  cmp file1 is equivalent to cmp file1 -; i.e., it will compare file1 to the standard input.  diff fails if invoked with one filename argument; you would need to say diff file1 -.
  • And, while dd will accept an input file specified on the command line if it is presented as if=filename, e.g.,

    dd if=my_iso_file of=/dev/sda1
    

    (of is output file), and it will read from standard input if you don't specify any if; e.g.,

    dd of=/dev/sda1 < my_iso_file
    

    it does not accept command line arguments that are unadorned filenames (so, for example, dd my_iso_file > /dev/sda1 and dd my_iso_file of=/dev/sda1 do not work).  (Also, unlike most commands that read from files, dd will not process more than one input file from the command line.)

(There are probably others.)

1
  • Technically, you can redirect a file into dd: dd status=none < /proc/uptime
    – Steven
    Jun 4, 2015 at 22:54
0

Read the documentation.

The echo command does not read from stdin. Therefore, input redirection does nothing. Bash manual states:

echo: Outputs args, separated by spaces, followed by a newline.

Man page for cat:

cat - concatenates files and print on the standard output.

You must log in to answer this question.

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