bash 中的 lambda 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/448126/
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
lambda functions in bash
提问by Daniel
Is there a way to implement/use lambda functions in bash? I'm thinking of something like:
有没有办法在 bash 中实现/使用 lambda 函数?我在想这样的事情:
$ someCommand | xargs -L1 (lambda function)
采纳答案by j_random_hacker
I don't know of a way to do this, however you may be able to accomplish what you're trying to do using:
我不知道有什么方法可以做到这一点,但是您可以使用以下方法完成您想要做的事情:
somecommand | while read -r; do echo "Something with $REPLY"; done
This will also be faster, as you won't be creating a new process for each line of text.
这也会更快,因为您不会为每一行文本创建一个新流程。
[EDIT 2009-07-09]I've made two changes:
[编辑 2009-07-09]我做了两个改变:
- Incorporated litb's suggestion of using
-rto disable backslash processing -- this means that backslashes in the input will be passed through unchanged. - Instead of supplying a variable name (such as
X) as a parameter toread, we letreadassign to its default variable,REPLY. This has the pleasant side-effect of preserving leading and trailing spaces, which are stripped otherwise (even though internal spaces are preserved).
- 合并了 litb 的使用
-r禁用反斜杠处理的建议——这意味着输入中的反斜杠将被原封不动地传递。 - 我们没有提供变量名称(例如
X)作为 的参数read,而是read将其分配给它的默认变量REPLY。这具有保留前导和尾随空格的令人愉快的副作用,否则将被剥离(即使保留了内部空间)。
From my observations, together these changes preserve everything except literal NUL (ASCII 0) characters on each input line.
根据我的观察,这些更改一起保留了每个输入行上除文字 NUL (ASCII 0) 字符之外的所有内容。
[EDIT 26/7/2016]
[编辑 26/7/2016]
According to commenter Evi1M4chine, setting $IFSto the empty string before running read X(e.g., with the command IFS='' read X) should also preserve spaces at the beginning and end when storing the result into $X, meaning you aren't forced to use $REPLY.
根据评论者 Evi1M4chine 的说法,$IFS在运行之前设置为空字符串read X(例如,使用命令IFS='' read X)还应该在将结果存储到 时保留开头和结尾的空格$X,这意味着您不会被迫使用$REPLY.
回答by Evi1M4chine
if you want true functions, and not just pipes or while loops (e.g. if you want to pass them around, as if they were data) I'd just not do lambdas, and define dummy functions with a recurring dummy name, to use right away, and throw away afterwards. Like so:
如果你想要真正的函数,而不仅仅是管道或 while 循环(例如,如果你想传递它们,就好像它们是数据一样)我只是不做 lambdas,并使用重复的虚拟名称定义虚拟函数,以正确使用扔掉,然后扔掉。像这样:
# An example map function, to use in the example below.
map() { local f=""; shift; for i in "$@"; do "$f" "$i"; done; }
# Lambda function [λ], passed to the map function.
λ(){ echo "Lambda sees "; }; map λ *
Like in proper functional languages, there's no need to pass parameters, as you can wrap them in a closure:
就像在适当的函数式语言中一样,不需要传递参数,因为您可以将它们包装在一个闭包中:
# Let's say you have a function with three parameters
# that you want to use as a lambda:
# (As in: Partial function application.)
trio(){ echo " Lambda sees "; }
# And there are two values that you want to use to parametrize a
# function that shall be your lambda.
pre="<<<"
post=">>>"
# Then you'd just wrap them in a closure, and be done with it:
λ(){ trio "$pre" "$post" "$@"; }; map λ *
I'd argue that it's even shorter than all other solutions presented here.
我认为它比这里介绍的所有其他解决方案还要短。
回答by Evi1M4chine
What about this?
那这个呢?
somecommand | xargs -d"\n" -I{} echo "the argument is: {}"
(assumes each argument is a line, otherwise change delimiter)
(假设每个参数都是一行,否则更改分隔符)
回答by dobrokot
if you want only xargs (due parallel -P Noption for example), and only bash as function code, then bash -ccan be used as parameter for xargs.
如果您只需要 xargs(-P N例如由于并行选项),并且只需要 bash 作为函数代码,则bash -c可以用作 xargs 的参数。
seq 1 10 | tr '\n' 'command='echo howdy'
eval "$command"
' | xargs -0 -n 1 bash -c 'echo any bash code #!/usr/bin/env bash
set -e
function multiplyBy() {
X=""
cat <<-EOF
Y="$1"
echo "$X * $Y = $(( $X * $Y ))"
EOF
}
function callFunc() {
CODE=""
shift
eval "$CODE"
}
MULT_BY_2=`multiplyBy 2`
MULT_BY_4=`multiplyBy 4`
callFunc "$MULT_BY_2" 10
callFunc "$MULT_BY_4" 10
'
tr and -0 option are used here to disable any xargs parameters substitutions.
tr 和 -0 选项用于禁用任何 xargs 参数替换。
回答by mcandre
Yes. One can pass around a string variable representing a command call, and then execute the command with eval.
是的。可以传递一个表示命令调用的字符串变量,然后使用 eval 执行命令。
Example:
例子:
##代码##回答by pinkeen
The eval trick has been already mentioned but here's my extended example of bash closures:
已经提到了 eval 技巧,但这是我的 bash 闭包扩展示例:
##代码##PS I've just came up with this for a completely different purpose and was just searching google to see if sb is using that. I actually needed to evaluate a reusable function in the context (shell) of main script.
PS 我只是为了一个完全不同的目的想出了这个,只是在谷歌上搜索 sb 是否正在使用它。我实际上需要在主脚本的上下文(shell)中评估一个可重用的函数。

