Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xargs doesn't recognize bash aliases

I'm trying to run the following command:

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar 

where "foobar" is an alias or function defined in my .bashrc file (in my case, it's a function that takes one parameter). Apparently xargs doesn't recognize these as things it can run. Is there a clever way to remedy this?

like image 983
Ian Greenleaf Young Avatar asked Feb 04 '09 22:02

Ian Greenleaf Young


People also ask

What does xargs do in bash?

The xargs command builds and executes commands provided through the standard input. It takes the input and converts it into a command argument for another command. This feature is particularly useful in file management, where xargs is used in combination with rm , cp , mkdir , and other similar commands.

How do you pass arguments to xargs?

The -c flag to sh only accepts one argument while xargs is splitting the arguments on whitespace - that's why the double quoting works (one level to make it a single word for the shell, one for xargs).

What can I use instead of xargs?

GNU parallel is an alternative to xargs that is designed to have the same options, but is line-oriented. Thus, using GNU Parallel instead, the above would work as expected.

Do bash scripts use aliases?

Bash Alias allows to aggregate multiple functions into a single command and also it avoids repetitive or large commands into a simple shortcut command.


2 Answers

Since only your interactive shell knows about aliases, why not just run the alias without forking out through xargs?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done 

If you're sure that your filenames don't have newlines in them (ick, why would they?), you can simplify this to

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done 

or even just find -iname '.#*' | ..., since the default directory is . and the default action is -print.

One more alternative:

 IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done 

telling Bash that words are only split on newlines (default: IFS=$' \t\n'). You should be careful with this, though; some scripts don't cope well with a changed $IFS.

like image 156
ephemient Avatar answered Oct 17 '22 08:10

ephemient


Using Bash you may also specify the number of args being passed to your alias (or function) like so:

alias myFuncOrAlias='echo'  # alias defined in your ~/.bashrc, ~/.profile, ... echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0 echo arg1 arg2 | xargs  bash -cil 'myFuncOrAlias "$@"' arg0 
like image 28
tilo Avatar answered Oct 17 '22 07:10

tilo