BASH函数在echo字符串中

时间:2013-02-23 06:47:48

标签: string bash function

我觉得自己像个白痴。我想要一个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对调用字符串内的函数有限制吗?它似乎有效,因为它输出的东西,但它没有执行数学运算。

3 个答案:

答案 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}"

另外,Stop using backticks