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. Seeman bash-builtins
. It only works in the context of bash so not anxargs
or-exec
forked subshell. -
type
is used to doing its own path searching. If you give it a path (asfind
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 intoxargs 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).