xargs doesn't recognize bash aliases

Command LineXargsBash

Command Line Problem Overview


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?

Command Line Solutions


Solution 1 - Command Line

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.

Solution 2 - Command Line

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

Solution 3 - Command Line

This doesn't work because xargs expects to be able to exec the program given as its parameter.

Since foobar in your case is just a bash alias or function there's no program to execute.

Although it involves starting bash for each file returned by find, you could write a small shell script thus:

#!/bin/bash
. $(HOME)/.bashrc
func $*

and then pass the name of that script as the parameter to xargs

Solution 4 - Command Line

Adding a trailing space to the command being aliased causes other aliased commands to expand:

alias xargs='xargs ' # aliased commands passed to xargs will be expanded

See this answer for more info:
https://stackoverflow.com/a/59842439/11873710

Solution 5 - Command Line

I usually use find like this:

find . -iname '' -exec cmd '{}' \;

'{}' will get replaced with the filename, and ; is necessary to terminate the execution chain. However, if that doesn't work with your function, you might need to run it through bash:

find .. |sed -e "s/.*/cmd '&'/"|bash

Find prints each file on a line, sed just prefixes this with your command, and then pipe it to bash for execution. Skip the |bash first to see what will happen.

Solution 6 - Command Line

try

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIan Greenleaf YoungView Question on Stackoverflow
Solution 1 - Command LineephemientView Answer on Stackoverflow
Solution 2 - Command LinetiloView Answer on Stackoverflow
Solution 3 - Command LineAlnitakView Answer on Stackoverflow
Solution 4 - Command Lineken hicksView Answer on Stackoverflow
Solution 5 - Command LineStaaleView Answer on Stackoverflow
Solution 6 - Command LineJacob AdamczykView Answer on Stackoverflow