Piping to "type" command

Solution 1:

type is not a normal command. It's a shell buitin. See:

$ type type
type is a shell builtin

So, you need to invoke bash with -c to achieve what you want

$ find . -name anacron | xargs -I '{}'  bash -c "type {}"

Or even simpler (no need for xargs):

$ find . -name anacron -exec bash -c "type {}"  \;

It will call bash -c "type ./file", with every file that is found by find. -I in xargs means, we define here a placeholder {} to use later. This placeholder is replaced with the filename found.

Why shell builtins don't work with xargs:

[...] Builtin commands are contained within the shell itself. When the name of a builtin command is used as the first word of a simple command, the shell executes the command directly, without invoking another program. [...]


xargs reads items from the standard input, [...], and executes the command

The command in this case is a simple excutable, and a shell builtin is not an executable. It cannot be found in the filesystem. It's within the shell itself. So you have to call the shell and tell the called shell to invoke the builtin command. That's what happend with bash -c "command".

Solution 2:

There are a few problems here (some already highlighted):

  • type is a builtin. It's not a command that's resolved, it's a function inside bash. See man bash-builtins. It only works in the context of bash so not an xargs or -exec forked subshell.
  • type is used to doing its own path searching. If you give it a path (as find is wont to do), it'll probably just return that path. readlink -f might be better if you're just trying to resolve symlinks; and you can pipe into xargs readlink or -exec readlink -f {} + all day long.

That's not to say you can't do what you're trying to. There are two options. The type command can handle many names at once so you could just provide it all the names at once:

type $(find /usr/sbin -name anacron)

For many commands, if there are too many arguments you'll exceed the command line length limit (see getconf ARG_MAX). However, that won't apply in this case since type is built into the shell and doesn't generate a new process ID (the length limit applies to the exec() function used by the child process in a normal command line).