I was trying to find all symbolic links in /usr/lib and use file on the first entry in the list, which I delimited with head -n 1.
Why does find /usr/lib -maxdepth 1 -type l | file $(head -n 1) work but find /usr/lib -maxdepth 1 -type l | head -n 1 | file does not?
It complains that I am not using file correctly. Probably because it lacks an argument, but - programmatically/syntactically - why can’t file grab it’s argument from the pipe?
Your syntax is fine, but not all commands/programs accept input from the pipe, or more accurately from stdin. Looking at the man page for file (https://www.man7.org/linux/man-pages/man1/file.1.html) I can’t see a stdin option, so you have to pass each of the files from your
headoutput as arguments to file.I learned this the hardway with ffmpeg… In my defense… Their documentation IS huge !!!
Kinda interested if
&1would also work in this case?&1pipes stderr to stdout, which would not affect a binary like file which doesn’t parse stdin. You would need something likexargs filewhich would convert the stdout to command line arguments.
Thanks! Yeah, I just came to the realization that this was more about my lack of understanding of the file command than anything else.
When you use the pipe you’re passing stdout from the left command to stdin on the right command.
file takes a filename as an argument, it does not read stdin (by default).
The first command works because head does read from stdin and then echoes the first line, but as an argument to file using command substitution - the $( … ) bit. Command substitution is neat but this is not really the best use-case for it.
A better way is to use find with -print0 which makes it use a zero-byte instead of a newline character (otherwise the command will fail in case a filename contains a newline - newlines and spaces in filenames break a lot of scripts if you aren’t careful) and -quit, which makes find exit after the first match. And then pass it to xargs which is a utility that transfers stdin to command arguments - In this case the file binary - and handles zero-bytes as seperators when using the -0 arg.
find /usr/lib -maxdepth 1 -type l -print0 -quit | xargs -0 fileRemoving -quit from the find command also works as expected (ie. on each found link).
Thanks! So this was more about my lack of understanding of how the file command works… But anyway, this gave me some new stuff to study! Especially the -print0 and -quit options and the xargs command.
@emotional_soup_88
You could use “-” as argument for file:find /usr/lib -maxdepth 1 -type l | head -n 1 | file -
which means, ‘file’ will read its input from the pipe. But that is probably not what you want, because ‘file’ parses the input and does not accept it as an argument.
You use a pipe to pass the output of a program to another program, in order to do something with that input. Like:
cat unsorted_list.txt | sort -
Thanks! I actually did try that, at which point it said “/dev/stdin ASCII text” or the likes, so it’s like the file command literally read the stdin device. Which was extremely intriguing, but not what I wanted. God, I love Linux :D
It’s not like it, it’s exactly it. The output from find is text,
-means read stdin, so file told you the text in stdin was text. You’ll have to see if it takes a list of files as an option, otherwise just use a for loop.
deleted by creator



