这是一个计算阶乘的简单 shell 函数。
#!/bin/bash
function factorial()
{
if (( $1 < 2 ))
then
echo 1
else
echo $(( $1 * $(factorial $(( $1 - 1 ))) ))
fi
}
factorial $1
但我发现当给定一个非常大的输入时,这个脚本会创建许多子 shell。这是没有必要的,而且效率不高。有没有什么方法可以在不创建新子 shell 的情况下调用递归函数?
我的目标不是如何在 shell 中编写阶乘函数,而是如何在调用递归定义的函数时避免创建子 shell。
事实上,即使是一个简单的函数调用也会导致子 shell 的创建:
#!/bin/bash
function fac0() {
ps >> log
echo $1
}
function fac1() {
ps >> log
echo $(( $1 * $(fac0 $(( $1 - 1 ))) ))
}
touch log
fac1 $1
运行脚本后,log
文件的内容是:(它仍然创建子 shell)
PID TTY TIME CMD
9205 pts/8 00:00:00 bash
9245 pts/8 00:00:00 call_subshell.s
9247 pts/8 00:00:00 ps
PID TTY TIME CMD
9205 pts/8 00:00:00 bash
9245 pts/8 00:00:00 call_subshell.s
9248 pts/8 00:00:00 call_subshell.s
9249 pts/8 00:00:00 ps
由于创建了子 shell,因此存在其他不需要的方面。
#!/bin/bash
declare -i i
i=0
function factorial() {
i=$(($i + 1))
if (( $1 < 2 ))
then
echo 1
else
local c=$(( $1 - 1 ))
echo $(( $1 * $(factorial $c) ))
fi
}
factorial $1
echo $i
无论参数是多少,这个脚本都会打印$i=1
!
最佳答案
避免递归:
#!/bin/bash
factorial() {
local f=1
for ((i=2; i<=$1; i++)) ; do
(( f *= i ))
done
echo $f
}
factorial $1
子 shell 是由于命令替换而产生的。使用“参数作为结果”的方式来避免它:
#!/bin/bash
# set -xv
factorial() {
# echo $BASH_SUBSHELL
if [[ $2 ]] ; then
if (( $2 == 1 )) ; then
echo $1
else
factorial $(( $1 * $2 )) $(( $2 - 1 ))
fi
else
factorial $1 $(( $1 - 1 ))
fi
}
factorial $1
关于bash - 递归调用函数时如何阻止bash创建子shell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33568055/