Ls and input redirection

I'd like to redirect contents of a file to ls command input:

ls -l < /home/john/1.txt

where 1.txt content is just:

/etc

I expected ls to list the content of file defined in /home/jonh1.txt - that is /etc dir but it seems to ignore the input stream - still lists the contents of the current dir insted of /etc dir as defined in /home/jonh1.txt file.


it seems to ignore the input stream

Yes. The ls program never uses the input stream, because it wasn't written to read anything from the input stream. This is not something that comes automatically with any Unix program – it has to be implemented separately.

Do not confuse the input stream (stdin) with the command-line arguments (argv); the former is an actual stream which can be read from line-by-line, while the latter is a simple read-only array of words. In your case, both are present and contain different data.

(Why shouldn't it be automatic for all programs? Well, take sort or cat or grep as an example. These programs accept different kinds of values – file names as arguments, but text as stdin contents. So you can pipe any command to | sort, and it sorts the input. But if stdin and command-line were the same thing, you couldn't pipe anything into | sort anymore because it would think that the pipe input was a list of filenames. Or vice versa, you couldn't give it filenames because it'd just sort the names.)

For an alternative take, see this explanation on StackOverflow (which you already got in the comments).


Try using xargs:

xargs ls -l < /home/john/1.txt

If you write any command line program that takes input from the user, you'll see very clearly what's going on. If a program has a read/readLine(different languages might give it a different name), statement, so, the program prompts the user for input, then you can also pipe or redirect that input in using | or <

If you look at a program that takes input, you see like with more or less, if you type it with no input $more<ENTER>, then it prompts for input. By piping data to it, it stops it prompting for input. If we run sed with no parameters $sed<ENTER> then sure it gives an error, and we can't do $echo abc|sed<ENTER> either. But if we do $sed 's/a/b/'<ENTER> then it prompts for input. And that's why echo abc|sed 's/a/b/'<ENTER> works.

You can see this if you write a program even as simple as Hello World but that takes input like the program prompts for a word and if the person types 'abc' it says "Hello abc". You'll be able to pipe to that program. It doesn't take any extra programming to get piping and redirection of input to work. If the program accepts keyboard input from the user then piping and redirection to it will work and then the program won't prompt for input.