xargs 无法识别 bash 别名

发布于 2024-07-13 03:24:09 字数 209 浏览 5 评论 0原文

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦醒灬来后我 2024-07-20 03:24:09

既然只有您的交互式 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=

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

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

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

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=

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.

\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.

久光 2024-07-20 03:24:09

在别名命令中添加尾随空格会导致其他别名命令展开:

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

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

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

最单纯的乌龟 2024-07-20 03:24:09

使用 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

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
半枫 2024-07-20 03:24:09

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

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

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

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

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

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

冰之心 2024-07-20 03:24:09

我通常使用这样的查找:

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

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

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

Find 将每个文件打印在一行上,sed 只是用您的命令作为前缀,然后将其通过管道传输到 bash 执行。 首先跳过 |bash 看看会发生什么。

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.

_蜘蛛 2024-07-20 03:24:09

尝试

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

try

find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文