2

このスクリプトの一貫性に少し問題があります。何の問題もなく、一度実行できます。ただし、すぐにロードして再度実行すると、出力が正しい方法でファイルに書き込まれないため、変数が正しく取得されません。

例: このユーティリティは、基本的に 4 つのファイルを更新するように設計されています。.temp、.tiers、.version、および .sync ダイアログ プロンプトのさまざまな段階で、ファイルを更新します。私の問題は、ファイルが更新されない場合があり、一度実行した後でのみ原因が見つからないことがあります。起動時にファイルを消去するので、何が問題なのかわかりません。記憶だけで掴んでいるような?

とにかく、これをテストするには、/test に以下のファイルが必要です。

どなたか教えていただけるとありがたいです。

cat .tiers
Stable=1
Release=2
Beta=3

コード:

#!/usr/bin/env bash
touch .version
touch .temp
VERSION=`cat .version`
DIR=/test/
STORED=`cat ${DIR}/.temp`
################################
#     REARRANGE TIERS          #
################################
rearrange()
{
start
end
}


################################
#     SYNC FILE EXISTS         #
################################
sync_exists()
{
dialog --msgbox ".sync exists in the directory $(echo ${VERSION}).\n\n Use Tier Move                 instead." 10 40
clean_up
exit 1;
}


################################
#         CLEAN UP             #
################################
clean_up()
{
rm -rf .version
rm -rf .update
rm -rf .temp
}

################################
#     OPTOUT & CLEAN UP        #
################################
opt_out()
{
dialog --msgbox "You've opted out of the tier update." 5 40
rm -rf ${DIR}/.version ${DIR}/.update ${DIR}/.temp 
}


################################
#     UPDATE .TIERS FILE       #
################################
tier_updater()
{
dialog --msgbox "\n\n
$(cat ${DIR}/.temp) is now $VERSION." 8 27
sed -i s/${STORED}=.*/${STORED}=${VERSION}/g ${DIR}/.tiers
clean_up
}



################################
#     UPDATE FILE LIST         #
################################
file_updater()
{

rm -rf ${VERSION}/.sync
        for x in `find $VERSION -type d \( ! -iname "." \)|sed s/${VERSION}//g`; do echo     "d===$x===755" >> ${DIR}/${VERSION}/.sync ; done
        for y in `find $VERSION -type f \( ! -iname ".*" \)|sed s/${VERSION}//g`; do     echo "f===$y===644===`md5sum ${VERSION}"$y"|awk '{print $1}'`" >>     "${DIR}"/"$VERSION"/.sync;done
        find "${DIR}"/"${VERSION}" -type f -exec gzip -f '{}' \; > /dev/null 2>&1      |xargs gzip -d "${DIR}"/${VERSION}/.sync
}



################################
#     TIER UPDATE PROMPT       #
################################
tier_update_prompt()
{
if [ -f ${VERSION}/.sync ]; then  sync_exists
else file_updater
fi
dialog --menu "\n
Directory List Built.\n
File List Built.\n
Files Compressed.\n
Sync File in place.\n\n
Would you like to update the tier for $(cat ${DIR}/.temp)?" \ 15 60 2  "Yes" "This will     apply all changes for $(echo $VERSION) to $(cat ${DIR}/.temp)." "No" "This will revert all     changes." 2>&1 > ${DIR}/.update
if [ "$?" = "0" ] ; then
        _update=$(cat ${DIR}/.update)
if [ "$_update" = "Yes" ] ; then
tier_updater
fi
if [ "$_update" = "No" ] ; then
opt_out ;
fi
else
        echo "You have now exited the application"
    clean_up;
fi
}

################################
#     NEW VERSION INPUT        #
################################ 
stable()
{
dialog --inputbox "Enter the new version for $(cat ${DIR}/.temp)" 8 30 2>     "${DIR}"/.version
if [ -d `cat .version` ] ; then tier_update_prompt;
        else
            dialog --msgbox "WARNING!!!!\n\n The folder $(${VERSION}) does not     exist!\nPlease upload this folder before you proceed!" 8 50 ;
        clean_up
    fi
}

################################
#        TIER SELECTION        #
################################
startup()
{
dialog --menu "Tiers are currently set as the following. Which would you like to update?    \n" 12 78 5 \
"Stable" "$(cat ${DIR}/.tiers|grep Stable|sed 's/Stable=//g')" "Release" "$(cat     ${DIR}/.tiers|grep Release|sed 's/Release=//g')" "Beta" "$(cat ${DIR}/.tiers|grep Beta|sed     's/Beta=//g')"  2> "${DIR}"/.temp
# OK is pressed
if [ "$?" = "0" ] ; then
        _return=$(cat ${DIR}/.temp)
fi
if [ "$_return" = "Stable" ] ; then
stable
fi
if [ "$_return" = "Release" ] ; then
stable
fi
if [ "$_return" = "Beta" ] ; then
stable
    else 
            echo "You have now exited the application"      
    clean_up;
fi
}
4

1 に答える 1

10

このメソッドを使用して、ダイアログ otput を変数に直接キャプチャできます。

exec 3>&1 
result=$(dialog  --menu head 15 20 6 $(for ((i=1;i<30;i++));do echo  tag$i item$i;done)  2>&1 1>&3);
exitcode=$?;
exec 3>&-;
echo $result $exitcode

http://mywiki.wooledge.org/BashFAQ/002

したがって、私のアプローチでは次のstartupようになります。

startup()
{
  exec 3>&1 
  _return=$(dialog --menu "Tiers are currently set as the following. Which would you like to update?    \n" 12 78 5 \
  "Stable" "$(cat ${DIR}/.tiers|grep Stable|sed 's/Stable=//g')" "Release" "$(cat     ${DIR}/.tiers|grep Release|sed 's/Release=//g')" "Beta" "$(cat ${DIR}/.tiers|grep Beta|sed     's/Beta=//g')"  2>&1 1>&3)
   exitcode=$?
   exec 3>&-;
    # OK is pressed
  if [ "$exitcode" == "0" ] ; then
    if [[ "$_return" == "Stable" || "$_return" == "Release" || "$_return" == "Beta" ]] 
    then
       stable
    fi
  fi
  echo "You have now exited the application"      
  clean_up;
}

さらに、 $(${VERSION}) のような多くの汚れたものがあります:

dialog --msgbox "WARNING!!!!\n\n The folder $(${VERSION}) does not

コードから理解しているように、起動時に .version が空であるため、空のコマンドが実行され、

 VERSION=`cat .version`

tier_update_prompt() で $VERSION はまだ空の文字列です。

私はあなたのコードをリファクタリングしようとしましたが、それは非常に多くの提案を台無しにしました:

  • 上記のようにダイアログの結果を取得する
  • パラメータを使用して関数を実行します。
#宣言
関数名() {
  パラメータ=$1;
  echo "$パラメータ"
}
var=値
#関数を実行
関数名変数     

  • ${VAR} を過度に複雑にしないでください。
  • 二重引用符は展開されることに注意echo "here is $var"してください。echo "here is $(echo ${var})"
  • たとえば、できるだけ少ない一時ファイルを使用します。diff <(ls dir1) <(ls dir2)
  • 作業ファイルをルート ディレクトリに保持しない (/test/ など)
  • ルートとして機能しない
  • パールを学ぶ
于 2012-11-17T02:55:37.050 に答える