Bash 脚本 : `exit 0` fails to exit

标签 bash exit freeze

所以我有这个 Bash 脚本:

#!/bin/bash

PID=`ps -u ...`
if [ "$PID" = "" ]; then
    echo $(date) Server off: not backing up
    exit
else
    echo "say Server backup in 10 seconds..." >> fifo
    sleep 10

    STARTTIME="$(date +%s)"

    echo nosave >> fifo
    echo savenow >> fifo
    tail -n 3 -f server.log | while read line
    do
        if echo $line | grep -q 'save complete'; then
            echo $(date) Backing up...
            OF="./backups/backup $(date +%Y-%m-%d\ %H:%M:%S).tar.gz"
            tar -czhf "$OF" data

            echo autosave >> fifo
            echo "$(date) Backup complete, resuming..."
            echo "done"
            exit 0
            echo "done2"
        fi

        TIMEDIFF="$(($(date +%s)-STARTTIME))"
        if ((TIMEDIFF > 70)); then
            echo "Save took too long, canceling backup."
            exit 1
        fi
    done
fi

基本上,服务器从 fifo 获取输入并输出到 server.log。 fifo 用于向服务器发送停止/启动命令以进行自动保存。最后,一旦它从服务器收到服务器已完成保存的消息,它就会 tar 数据目录并再次开始保存。

我在 exit 0 行遇到了麻烦。一切都执行得很好,但我得到了这个输出:

srv:scripts $ ./backup.sh
Sun Nov 24 22:42:09 EST 2013 Backing up...
Sun Nov 24 22:42:10 EST 2013 Backup complete, resuming...
done

但它卡在那里。请注意“done”如何回显但“done2”失败。某些原因导致它在 exit 0 处挂起。

附录:为了避免以后看到这个的人感到困惑,它卡在退出行并且永远不会返回到命令提示符。不确定我的原始描述是否足够清楚。

有什么想法吗?这是整个脚本,没有其他任何事情发生,我直接从 bash 调用它。

最佳答案

这是一个表现出相同行为的更小的自包含示例:

echo foo > file
tail -f file | while read; do exit; done

问题在于,由于管道的每个部分都在子 shell 中运行,exit 仅退出 while read 循环,而不是整个脚本。

然后它将挂起,直到 tail 找到一个新行,尝试写入它,并发现管道坏了。

要修复它,你可以更换

tail -n 3 -f server.log | while read line
    do
       ...
    done

while read line
do
   ...
done  <  <(tail -n 3 -f server.log)

通过从进程替换重定向,流程不必像在管道中那样等待 tail 完成,并且它不会在子 shell 中运行,因此 exit 实际上会退出整个脚本。

关于Bash 脚本 : `exit 0` fails to exit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20184390/

相关文章:

python - python进程返回代码-9是什么意思?

android - 如何避免 Android getSystemService(Context.SENSOR_SERVICE) 挂起模拟器?

bash 脚本错误让 : -: syntax error: operand expected (error token is "-")

linux - 计算给定分区的已用磁盘空间百分比的 bash 脚本

linux - 在 Ubuntu 14.04 中使用 Bash 作为 eclipse 外部工具和 node.js

bash 运行命令而不退出错误并告诉我它的退出代码

c++ - 当退出时 C++ 中的库不是 "cleaned up"时会发生什么

Android:当用户单击后退按钮退出应用程序时显示 mopub 插页式广告

python - Unicode 在 .py 脚本中有效,但在卡住的 .exe 中无效 [Python 2.7]

visual-studio-2008 - VS 2008 Intellisense 卡在右键单击上