Difference between xargs /bin/ls and exec ls?

Solution 1:

  1. you need to quote the * in the second find command,

  2. the /dev/fd/* are devices which corresponds with stdin, stdout, stderr etc. thouse devices are simlinked and are different for each process,

  3. the -type f says, the result has to be regular file, thus the /dev/fd/* are not in the result as they are block devices,

  4. the xargs ls -l does the same as your ls -l {}... I even doubt the better performance in this case, but xargs is smarter and there are reasons to use it, eg. correct handling of files with whitespaces inside it,

If you are debugging the second version of your find, first of all see the output w/o the | xargs ls -l part

Solution 2:

Your first command executes a new ls command for every filename which matches the name you provided. This includes directories, symbolic links, devices, and anything else that can be found. The ls command gets executed as files are found, so you will see listings as the files are found.

The second command only matches file with the specified name. Because you did not quote GOALS*, if you run from a directory with a matching entry, it will replace the GOALS* entry in the command. xargs calls ls will a long list of file names. You won't see results until either the find finishes, or a sufficiently long list of matches is found. Because of parsing rules filename which contain whitespace will cause problems.

These three commands should be equivalent for files without white space in the name. The third option does not work on all operating systems, but handles white space in the name.

find / -name 'GOALS*' -type f -exec ls -l {} \;
find / -name 'GOALS*' -type f | xargs /bin/ls -l
find / -name 'GOALS*' -type f -print0 | xargs -0 /bin/ls -l