xargs 无法识别 bash 别名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/513611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 20:39:33  来源:igfitidea点击:

xargs doesn't recognize bash aliases

command-linexargsbash

提问by Ian Greenleaf Young

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 不能将这些识别为它可以运行的东西。有没有聪明的方法来解决这个问题?

采纳答案by ephemient

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

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

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.

甚至只是find -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.

回答by tilo

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

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

alias myFuncOrAlias='echo'  # alias defined in your ~/.bashrc, ~/.profile, ...
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias ""' arg0
echo arg1 arg2 | xargs  bash -cil 'myFuncOrAlias "$@"' arg0

回答by Alnitak

This doesn't work because xargsexpects to be able to execthe programgiven as its parameter.

这不起作用,因为xargs期望能够exec程序作为其参数给出。

Since foobarin your case is just a bashalias or function there's no program to execute.

由于foobar在您的情况下只是bash别名或函数,因此没有要执行的程序。

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

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

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

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

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

回答by ken hicks

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

有关更多信息,请参阅此答案:https:
//stackoverflow.com/a/59842439/11873710

回答by Staale

I usually use find like this:

我通常像这样使用 find:

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 看看会发生什么。

回答by Jacob Adamczyk

try

尝试

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