1

我觉得自己像个白痴。我想要一个 BASH 函数,它每次调用时都会交替值。脚本本身很简单,直接调用函数就可以了。但是在字符串中调用时它的工作方式不同。这是代码:

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 对在字符串中调用函数有限制吗?它似乎有效,因为它正在输出一些东西,但它没有执行数学运算。

4

3 回答 3

2

反引号创建子外壳,并且在每个子外壳中重置环境,因此您实际上不会修改相同的变量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>"
于 2013-02-23T06:55:21.330 回答
1

也许不是最优雅的解决方案,但您可以使用文件描述符,因为它们被子进程(例如子shell)继承。

正如已经指出的那样,(反引号)子shell(子进程)中的变量分配(例如您的let "ODDEVEN+=1"or let "ODDEVEN-=1")对父shell(父进程)是不可见的。

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>
于 2013-02-23T13:19:50.897 回答
0

在这种情况下,目标是让函数脱离子外壳。

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 或更高版本中使用不创建子外壳的特殊命令替换形式。

function odd_or_even {
    ...
}

print -r -- "${prefix}${ odd_or_even;}${suffix}"

顺便说一句,停止使用反引号

于 2013-02-23T11:37:33.103 回答