2

I'd like to be able to pass in a modified grep command to xargs. I am overriding a command with a function in bash similar to Is it possible to override the command line's built in "cd" command?. My function below works, except when passing to xargs. Why is this and how do I work around this?

redefined:

function grepc() { $(which grep) -c "$@"; }

works:

find -name '*.py' | grepc web
2

xargs fails:

find -name '*.py' | xargs grepc import
xargs: grepc: No such file or directory

(passing to xargs here should grep the file contents of the python list, which is a weird contrived example but the point is xargs can't find grepc)

TLDR: why can't | xargs <function> work? Does <function> actually need to be a <builtin> or something?

barrrista
  • 1,749

2 Answers2

4

Whatever xargs runs, it is its direct child process, there's no shell between them. xargs has no concept of your function. It also has no concept of shell builtins.

To make it work:

  • either export your function (with export -f grepc) and make xargs run a shell in a somewhat cumbersome way: … | xargs bash -c 'grepc "$@"' bash
  • or better convert your function to a script, make the file executable and place it where your $PATH points to (or adjust the variable); then grepc will be a file and xargs will be able to run it.
0

Another workaround that came to me:

alias xg='xargs grep --color <or whatever else I want>'

Since I use this combination so frequently.

barrrista
  • 1,749