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

おそらく最も洗練されたソリューションではありませんが、ファイル記述子は子プロセス(サブシェルなど)に継承されるため、ファイル記述子を使用できます。

すでに指摘したように、(バッククォートされた)サブシェル(子プロセス)の変数割り当て(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>
于 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およびmkshR41以降でのみ可能です。

function odd_or_even {
    ...
}

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

余談ですが、バックティックの使用をやめてください。

于 2013-02-23T11:37:33.103 に答える