odd_or_even()
{
if [ $ODDEVEN -eq 1 ]; then
echo "odd"
let "ODDEVEN+=1"
else
echo "even"
let "ODDEVEN-=1"
fi
}
ODDEVEN=1
odd_or_even # Prints "odd"
odd_or_even # Prints "even"
echo "<td class=\"`odd_or_even`\">Test</td>" # Prints class=odd
echo "<td class=\"`odd_or_even`\">Test</td>" # Prints class=odd
BASH对调用字符串内的函数有限制吗?它似乎有效,因为它输出的东西,但它没有执行数学运算。
答案 0 :(得分:2)
后引号创建子shell,并在每个子shell中重置环境,因此您实际上不会修改相同的变量ODDEVEN
。
您可以使用文件:
odd_or_even()
{
ODDEVEN=$(cat oddfile)
if [ $ODDEVEN -eq 1 ]; then
echo "odd"
let "ODDEVEN=0"
else
echo "even"
let "ODDEVEN=1"
fi
echo $ODDEVEN > oddfile
}
或者让函数执行字符串操作:
odd_or_even()
{
prefix=$1
suffix=$2
if [ $ODDEVEN -eq 1 ]; then
out="odd"
let "ODDEVEN=0"
else
out="even"
let "ODDEVEN=1"
fi
echo $prefix$out$suffix
}
ODDEVEN=1
odd_or_even "<td class=\"" "\">Test</td>"
odd_or_even "<td class=\"" "\">Test</td>"
答案 1 :(得分:1)
也许不是最优雅的解决方案,但您可以使用文件描述符,因为它们被子进程(例如子shell)继承。
正如已经指出的那样,父shell(父进程)看不到(回退)子shell(子进程)中的变量赋值(例如let "ODDEVEN+=1"
或let "ODDEVEN-=1"
)。
odd_or_even()
{
if [ $ODDEVEN -eq 1 ]; then
#echo "odd"
exec 3<&-
exec 3<<<"odd"
let "ODDEVEN+=1"
else
#echo "even"
exec 3<&-
exec 3<<<"even"
let "ODDEVEN-=1"
fi
}
export -f odd_or_even
{
ODDEVEN=1
odd_or_even && cat <&3 3<&- # Prints "odd"
odd_or_even && cat <&3 3<&- # Prints "even"
odd_or_even
echo "<td class=\"`cat <&3 3<&-`\">Test</td>" # Prints class=odd
odd_or_even
echo "<td class=\"`cat <&3 3<&-`\">Test</td>" # Prints class=odd
}
# output:
# odd
# even
# <td class="odd">Test</td>
# <td class="even">Test</td>
答案 2 :(得分:0)
这种情况下的目标是将功能从子shell中删除。
function odd_or_even {
case $oddeven in
?([01]))
typeset -a strings=(even odd)
printf %s "${strings[oddeven^=1]}"
;;
*) return 1
esac
}
odd_or_even > >(echo "${prefix}$(</dev/fd/0)${suffix}") || exit
由于您无论如何都要分配给非局部变量,因此不仅仅是直接使用它而不是担心I / O。这使得两半都不在子壳内。
oddeven=
typeset -a strings=(even odd)
echo "${prefix}${strings[oddeven^=1]}${suffix}"
原始解决方案只能在ksh93t和mksh R41或更高版本中使用不创建子shell的特殊命令替换表单。
function odd_or_even {
...
}
print -r -- "${prefix}${ odd_or_even;}${suffix}"