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
xargs doesn't recognize bash aliases
提问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)

