I've been studying about the command line and learned that |
(pipeline) is meant to redirect the output from a command to the input of another one.
So why does the command ls | file
doesn't work?
file
input is one of more filenames, like file filename1 filename2
ls
output is a list of directories and files on a folder, so I thought ls | file
was supposed to show the file type of every file on a folder.
When I use it however, the output is:
Usage: file [-bcEhikLlNnprsvz0] [--apple] [--mime-encoding] [--mime-type]
[-e testname] [-F separator] [-f namefile] [-m magicfiles] file ...
file -C [-m magicfiles]
file [--help]
As there was some error with the usage of the file
command
Best Answer
The fundamental issue is that
file
expects file names as command-line arguments, not on stdin. When you writels | file
the output ofls
is being passed as input tofile
. Not as arguments, as input.What's the difference?
Command-line arguments are when you write flags and file names after a command, as in
cmd arg1 arg2 arg3
. In shell scripts these arguments are available as the variables$1
,$2
,$3
, etc. In C you'd access them via thechar **argv
andint argc
arguments tomain()
.Standard input, stdin, is a stream of data. Some programs like
cat
orwc
read from stdin when they're not given any command-line arguments. In a shell script you can useread
to get a single line of input. In C you can usescanf()
orgetchar()
, among various options.file
does not normally read from stdin. It expects at least one file name to be passed as an argument. That's why it prints out usage when you writels | file
, because you didn't pass an argument.You could use
xargs
to convert stdin into arguments, as inls | xargs file
. Still, as terdon mentions, parsingls
is a bad idea. The most direct way to do this is simply: