1

我编写了简单的 bash 脚本来从 iblocklist.com 获取存档并将其提取到我的传输阻止列表目录中。在它多次运行失败后,我发现 iblocklist 推送的 .gz 存档已损坏,但 .zip 没有,所以我决定实现一些错误捕获和完成任务的替代方法。重写脚本后,我收到意外的 EOF 错误,我找不到问题所在。我绝不是 bash 的高级用户,但我通常可以通过反复试验和谷歌来完成我想要的。今天不行。我一直在寻找明显缺失的 }、fi 和 ;,但它对我来说看起来不错。不确定这是否重要,但在这台机器上,我正在运行一个 Backtrack linux 发行版,它或多或少地迫使你始终成为 root。我是初学者所以请温柔:)

#!/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

问题是您使用}fi来终止if. 令牌}fi不是fi. 所以文件末尾的 shell 有很多 openif缺少它们fi的 s。

您迫切需要阅读 shell 手册、理解 shell 语法并询问当地的 shell 专家。编写的脚本是 fubar,即使语法错误已更正。

于 2013-02-19T16:22:29.557 回答
0

像你一样使用大括号是一种有点不寻常的风格,但它没有任何问题。然而,shell 对空格有点挑剔:

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,shell 将在任何命令失败时立即退出。

于 2013-02-19T17:09:12.170 回答