1

iblocklist.com からアーカイブを取得し、それを送信ブロックリスト ディレクトリに抽出する簡単な bash スクリプトを作成しました。何度か実行に失敗した後、iblocklist によってプッシュされた .gz アーカイブが破損していることがわかりましたが、.zip は破損していないため、エラー キャッチとタスクを達成するための代替手段を実装することにしました。スクリプトを書き直した後、予期しない EOF エラーが発生し、どこに問題があるのか​​ わかりません。私は決して bash の上級ユーザーではありませんが、通常は、試行錯誤と Google を使用して目的を達成できます。今日ではありません。明らかな欠落している}、fi、および;を探しましたが、それは私には良さそうです。問題があるかどうかはわかりませんが、このマシンでは、多かれ少なかれ常にルートになるように強制するBacktrack Linuxディストリビューションを実行しています。初心者なのでお手柔らかにお願いします(;_;)

#!/bin/bash

function test {
    "$@"
        STATUS=$?
    if [ $STATUS -ne 0 ]; then
        echo "error with $1";
    fi

    return $STATUS
}

function askyn {
    read -p "The operation failed. Try alternate means? [Y/n] " -n 1 -r
    if [[ "$REPLY" =~ ^[Yy] ]] || [[ "$REPLY" = "" ]]; then YN=1;
    else YN=0; fi
    return $YN
}

function cleanup {
    if [ $ALT == 0 ]; then {
        test rm /root/scripts/.lvl1/dl/level1.gz
        if [ $STATUS -ne 0 ]; then {
            echo Removal of archive failed
        }fi
    }else {
        test rm /root/scripts/.lvl1/dl/level1.zip
        if [ $STATUS -ne 0 ]; then {
            echo Removal of archive failed
        }fi
    }fi
    return
}

ALT=0
YN=-1
test wget "http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=gz" -O /root/scripts/.lvl1/dl/level1.gz
if [ $STATUS -ne 0 ]; then { #wget failed first try
    askyn
    if [ $YN == 1 ]; then ALT=1;else exit;fi #prompt for alternate; exit if not
}else { #wget worked first try
    test file-roller -e /root/.config/transmission/blocklists /root/scripts/.lvl1/dl/level1.gz
    if [ $STATUS -ne 0 ]; then { #file-roller failed to extract the list
        askyn
        if [ $YN == 1 ]; then ALT=1;else exit;fi #prompt for alternate; exit if not
    }else { #everything worked first try
        echo Download and extraction successful
        cleanup
    }fi
}fi
if [ $ALT == 1 ]; then { #try to wget .zip
    test wget "http://list.iblocklist.com/?list=bt_level1&fileformat=p2p&archiveformat=zip" -O /root/scripts/.lvl1/dl/level1.zip
    if [ $STATUS -ne 0 ]; then { #wget of .zip failed
        echo Alternate means failed.  Exiting.
        exit
    }else { #wget of .zip worked 
        test unzip -o -d /root/.config/transmission/blocklists /root/scripts/.lvl1/dl/level1.zip #try to unzip .zip
        if [ $STATUS -ne 0 ]; then { #unzip failed
            echo Alternate means failed.  Exiting.
            exit
        }else { #everything worked second try
            echo Download and extraction successful using alternate means
            cleanup
        }fi
    }fi
}fi
4

2 に答える 2

0

中かっこをそのまま使用するのは少し変わったスタイルですが、問題はありません。ただし、シェルは空白について少し厄介です。

if cmd; then {
    : commands
} else {
    : other commands
} fi

}との間のスペースに注意してくださいfi

また、あなたはあまりにも一生懸命働いています。常に明示的にチェック$?してエラーメッセージを書き込む代わりに、次のようにします。

if rm /root/scripts/.lvl1/dl/level1.gz; then
    : # perform some commands if the remove succeeded
else
    : # perform some commands on failure, but DO NOT PRINT AN ERROR MESSAGE
fi

エラーメッセージを出力しない理由は、rmコマンドがすでにエラーメッセージを出力しているはずであるということです。コマンドが失敗したときに終了することだけを計画している場合は、物事を単純化して次のことを実行できます。

rm /p/a/t/h || exit 1

次の手順を実行するだけで、さらに単純化できます。

#!/bin/sh -e
rm /p/a/t/h

を設定する-eと、コマンドが失敗するとシェルはすぐに終了します。

于 2013-02-19T17:09:12.170 に答える
0

問題は、}fiを終了するために を使用することifです。トークン}fiは ではありませんfiifしたがって、ファイルの最後のシェルには、 が欠落している多数の open がありますfi

シェルのマニュアルを読み、シェルの文法を理解し、地元のシェルの専門家に尋ねる必要があります。構文エラーが修正されていても、書かれたスクリプトは fubar です。

于 2013-02-19T16:22:29.557 に答える