xargs 无法识别 bash 别名

Posted

技术标签:

【中文标题】xargs 无法识别 bash 别名【英文标题】:xargs doesn't recognize bash aliases 【发布时间】:2010-10-05 13:03:44 【问题描述】:

我正在尝试运行以下命令:

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

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

【问题讨论】:

这是我在 ~/bin 文件夹中创建脚本而不是创建 bash 别名的原因之一。这样,我可以在任何 shell 中使用我的别名:BASH、ZSH、IPYTHON 或 FISH。 这是一个类似(虽然不相同)的问题:***.com/questions/979453/… 【参考方案1】:

我通常这样使用find:

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

'' 将被替换为文件名,而 \;是终止执行链所必需的。但是,如果这不适用于您的函数,您可能需要通过 bash 运行它:

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

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

【讨论】:

如果您使用的是新的 GNU find,请改用 -exec cmd '' +:这更像 xargs,因为它会将参数一起批处理到一次运行中,而不是为每个文件执行一个新的 cmd找到了。 我宁愿认为,如果他的函数能够接受多个参数,他就不会向 xargs 提供 -L 1 选项... 哦,这就是 -L 的作用?我没有查,为此我使用了 -n。 遗憾的是,这些方法仍然不适用于别名和函数。可能是因为 .bashrc 仅被交互式 shell 调用。但第一个是一个巧妙的技巧。【参考方案2】:

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

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

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

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

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

【讨论】:

我应该将该脚本放在哪里,以便xargs能够识别 @NickVolynkin 任何你想要的地方,只要它在$PATH 或直接将它的位置提供给xargs【参考方案3】:

既然只有你的交互式 shell 知道别名,为什么不直接运行别名而不通过xargs 分叉?

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

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

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

甚至只是find -iname '.#*' | ...,因为默认目录是.,默认操作是-print

另一种选择:

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

告诉 Bash 单词仅在换行符处拆分(默认值:IFS=$' \t\n')。不过,您应该小心这一点;一些脚本不能很好地处理更改后的$IFS

【讨论】:

这个答案是回答为什么我们不能使用 xargs 以及我们如何使用 xargs 和别名。 这个答案为我们提供了使用 xargs 的替代方法。对于使用 xargs 的答案,请参阅@camh 在相关问题中的答案:***.com/questions/979453/…(Nathan Fellman 链接到上面) xargs 可以使用并行模式,所以 while 不适合【参考方案4】:

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

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

【讨论】:

【参考方案5】:

试试

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

【讨论】:

【参考方案6】:

为被别名的命令添加尾随空格会导致其他别名命令扩展:

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

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

【讨论】:

以上是关于xargs 无法识别 bash 别名的主要内容,如果未能解决你的问题,请参考以下文章

为啥 hive 无法识别选择部分中命名的别名?

Angular 11 tsconfig 路径别名无法识别

未捕获的错误:[Ext.createByAlias] 无法创建无法识别别名的实例:小部件

.spec 文件中无法识别 Angular 8+ tsconfig 路径别名

PhpStorm 无法识别使用 webpack 别名导入的 Sass 文件

Resharper 无法识别 web.config 中的命名空间别名