您的问题只问如何导出函数。在bash中很容易,见下面。
您的问题标题/主题暗示可以在xargs中使用函数,就好像它们是脚本一样。
我不知道xargs是否可以直接“调用”bash函数,但您当然可以将导出的函数的使用包装在一个由
xargs
调用的脚本中,见下面。
首先,一个列出函数的函数。默认情况下是用户函数,并使用-v列出所有函数:
lsfns () {
case "$1" in
-v | v*)
set | grep '()' --color=always
;;
*)
declare -F | cut -d" " -f3 | egrep -v "^_"
;;
esac
}
下面是导出所有用户函数的函数:
exportfns () { export -f $(lsfns); }
或者只需将export -f $(lsfns)
放置于您的.bashrc
中。
示例脚本doit.sh:
#!/bin/bash
lsfns "$@"
chmod a+rx doit.sh
之后的示例命令行如下:
echo -v | xargs doit.sh
与之相比
echo "" | xargs doit.sh
编辑1:回复kdb下面的评论/答案(“遇到无法导出函数的情况”):
导出shell函数不与Posix兼容,即仅适用于Bash和可能的其他Shell,例如Zsh、Ksh等。
也就是说,在Dash和“标准”的Posix Shell中不提供“export -f”,我们无法导出函数。如果我们在Bash中导出一个函数,然后运行一个以sh-bang开头的脚本,例如“#!/bin/dash”,那么该脚本将无法使用父Shell中“导出”的函数,因为由Bash导出到“进程环境”的函数不被Dash识别。
编辑2:回复OP的评论“但如果myfunction
依赖于其他函数,则这将变得难以维护”:
这可能是可以充分利用shell源命令(别名“。”)的情况,例如:
. ~/etc/my-functions.sh
同样地,如果您更喜欢在函数中“生活”,而不是在脚本文件中,例如,当您需要时调用
myMain
,那么这个函数的第一行可以是引用您的函数库的源代码;
由于在“定期运行脚本”的情况下,这将是多余的开销,因此
myMain
成为命令行存根函数,用于(重新)加载您的函数库,并调用
actuallyDoit
函数(如果您有一个脚本文件,则也会从该脚本内部调用该函数)。
祝愉快
Zenaan
exportfns
会有所帮助)。 - kdbfind dir/ | xargs aBashFn
这样是行不通的-必须将该函数包装在脚本中,或者像你第一个例子中那样生成一个bash子shell。但分叉bash是一种相当沉重的调用函数的方式,除非你只需要它一次。希望这能解释我为什么写这个的原因... - zenaanxargs sh -c
,当我将其替换为xargs bash -c
时,所有我的export -f
函数都可以正常工作了!" - Noah Sussman