是否可以将命令块视为匿名函数?
function wrap_this {
run_something
# Decide to run block or maybe not.
run_something else
}
wrap_this {
do_something
do_somthing else
}
# Do something else
wrap_this {
do_something_else_else
do_something_else_else_else
}
Run Code Online (Sandbox Code Playgroud)
(我意识到您为每个块创建了一个函数或文件,但我发现此选项在某些情况下更清晰易读。)
while用做它do/done,并function与它做{ multiple lines }。我意识到 BASH 没有匿名函数,但是是否可以将多个命令传递给另一个函数,就像在定义函数或while?
小智 6
\n\n
这是我能想到的最短的解决方案:
\n\n鉴于这些功能:
\n\n# List processing\nmap() { while IFS=\'\' read -r x; do "$@" "$x"; done; }\nfilter() { while IFS=\'\' read -r x; do "$@" "$x" >&2 && echo "$x"; done; }\nfoldr() { local f="$1"; local result="$2"; shift 2; while IFS=\'\' read -r x; do result="$( "$f" "$@" "$x" "$result" )"; done; echo "$result"; }\nfoldl() { local f="$1"; local result="$2"; shift 2; while IFS=\'\' read -r x; do result="$( "$f" "$@" "$result" "$x" )"; done; echo "$result"; }\n\n# Helpers\nre() { [[ "$2" =~ $1 ]]; }\nRun Code Online (Sandbox Code Playgroud)\n\n例子:
\n\n# Example helpers\ntoLower() { tr \'[:upper:]\' \'[:lower:]\'; }\nshowStructure() { [[ "$1" == "--curly" ]] && echo "{$2; $3}" || echo "($1, $2)"; }\n\n# All lib* directories, ignoring case, using regex\nls /usr | map toLower | filter re \'lib.*\'\n\n# All block devices. (Using test, for lack of a full bash [[ \xe2\x80\xa6 ]].)\ncd /dev; ls | filter test -b\n\n# Show difference between foldr and foldl\n$ ls / | foldr showStructure \'()\'\n(var/, (usr/, (tmp/, (sys/, (sbin/, (run/, (root/, (proc/, (opt/, (mnt/, (media/, (lost+found/, (lib64/, (lib32/, (lib@, (home/, (etc/, (dev/, (daten/, (boot/, (bin/, ())))))))))))))))))))))\n$ ls / | foldr showStructure \'{}\' --curly\n{var/; {usr/; {tmp/; {sys/; {sbin/; {run/; {root/; {proc/; {opt/; {mnt/; {media/; {lost+found/; {lib64/; {lib32/; {lib@; {home/; {etc/; {dev/; {daten/; {boot/; {bin/; {}}}}}}}}}}}}}}}}}}}}}}\nRun Code Online (Sandbox Code Playgroud)\n\n(这些示例当然只是用法示例,实际上,这种风格只对更复杂的用例有意义。)
\n\n一般来说,可以使用以下样式:
\n\nf() { something "$@" ; }; someList | map f\ng() { something "$1" "$2" \xe2\x80\xa6; }; someCommand | filter g\n\xe2\x8b\xae \xe2\x8b\xae \xe2\x8b\xae \xe2\x8b\xae\nRun Code Online (Sandbox Code Playgroud)\n\n它\xe2\x80\x99s 不完全是lambda,但非常接近。只有几个多余的字符。
\n\n但据我所知,以下任何方便的缩写都不起作用:
\n\n\xce\xbb() { [[ $@ ]]; } # fails on spaces\n\xce\xbb() { [[ "${@:-1}" ${@:1:-1} ]]; } # syntax error\nalias \xce\xbb=test # somehow ignored\nRun Code Online (Sandbox Code Playgroud)\n\n不幸的是,bash它不太适合这种风格,尽管它的一些功能具有非常实用的风格。
小智 5
我已经成功地通过黑客做了你想做的事eval。在此我警告说eval 是不安全的,你应该不惜一切代价避免。话虽如此,如果您相信您的代码不会被滥用,您可以使用:
wrap_this(){
run_something
eval "$(cat /dev/stdin)"
run_something_else
}
Run Code Online (Sandbox Code Playgroud)
这允许您运行代码如下:
wrap_this << EOF
my function
EOF
Run Code Online (Sandbox Code Playgroud)
并不完全理想,因为内部块是一个字符串,但确实创建了重用。