xargs无法识别bash别名

时间:2022-09-17 20:27:56

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?

其中“foobar”是我的.bashrc文件中定义的别名或函数(在我的例子中,它是一个带有一个参数的函数)。显然xargs不会将这些视为可以运行的东西。有没有一种聪明的方法可以解决这个问题?

5 个解决方案

#1


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

由于只有您的交互式shell知道别名,为什么不在不通过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

如果您确定您的文件名中没有换行符(ick,为什么会这样?),您可以将其简化为

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.

甚至只是找到-iname'。#*'| ...,因为默认目录是。并且默认操作是-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.

告诉Bash,单词只在换行符上分割(默认值:IFS = $'\ t \ n')。不过,你应该小心这一点;一些脚本无法很好地应对已更改的$ IFS。

#2


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

使用Bash,您还可以指定传递给别名(或函数)的args数量,如下所示:

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

#3


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

这不起作用,因为xargs希望能够执行作为参数给出的程序。

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

因为在你的情况下foobar只是一个bash别名或函数,所以没有程序可以执行。

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

虽然它涉及为find返回的每个文件启动bash,但您可以编写一个小的shell脚本:

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

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

然后将该脚本的名称作为参数传递给xargs

#4


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:

'{}'将替换为文件名,并且\;是必要的终止执行链。但是,如果这对您的函数不起作用,您可能需要通过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.

Find在一行上打印每个文件,sed只是用你的命令作为前缀,然后将它传递给bash执行。首先跳过| bash,看看会发生什么。

#5


try

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

#1


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

由于只有您的交互式shell知道别名,为什么不在不通过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

如果您确定您的文件名中没有换行符(ick,为什么会这样?),您可以将其简化为

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.

甚至只是找到-iname'。#*'| ...,因为默认目录是。并且默认操作是-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.

告诉Bash,单词只在换行符上分割(默认值:IFS = $'\ t \ n')。不过,你应该小心这一点;一些脚本无法很好地应对已更改的$ IFS。

#2


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

使用Bash,您还可以指定传递给别名(或函数)的args数量,如下所示:

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

#3


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

这不起作用,因为xargs希望能够执行作为参数给出的程序。

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

因为在你的情况下foobar只是一个bash别名或函数,所以没有程序可以执行。

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

虽然它涉及为find返回的每个文件启动bash,但您可以编写一个小的shell脚本:

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

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

然后将该脚本的名称作为参数传递给xargs

#4


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:

'{}'将替换为文件名,并且\;是必要的终止执行链。但是,如果这对您的函数不起作用,您可能需要通过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.

Find在一行上打印每个文件,sed只是用你的命令作为前缀,然后将它传递给bash执行。首先跳过| bash,看看会发生什么。

#5


try

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