bash的陷阱后恢复 [英] Recover after bash trap

查看:133
本文介绍了bash的陷阱后恢复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和一些文件操作一个bash脚本,我想处理一个循环,直到pressing控制-C后,块的结尾。我做了一个例子:

I've a bash script with some file manipulations and I would like to process a loop until the end of the block after pressing Control-C. I've made an example:

#!/bin/bash

# Register signal handler
ABORT=0;
trap ABORT=1 SIGINT;

# Create temp dir
TEMPDIR=$(mktemp -d -t $0);

# Helper functions
function do_other_stuff {
    true;
}

# Process files
for ((COUNTER = 0; COUNTER < 3 && ABORT == 0; COUNTER++)); do
    FILE=/some/directory/$COUNTER.txt;
    BASE=$(basename $FILE);
    cp $FILE $TEMPDIR;
    > $FILE;
    do_other_stuff;
    cp $TEMPDIR/$BASE $FILE;
    rm $TEMPDIR/$BASE;
done;

rm -rf $TEMPDIR;

这似乎运作得很好,但我注意到,有时BASE在声明

This seems to work quite well, but I noticed, that sometimes BASE in the statement

BASE=$(basename $FILE);

没有设置,如果陷阱发生的基本部分命令期间发生。这导致在CP错误和下面的命令

is not set, if the trap happens to occur during the basename command. This leads to errors in the cp and following commands.

我是否错过了什么呢?如何猛砸从陷阱中恢复的用意何在?是否存在具有相同效果的另一种解决方案?

Do I miss something there? How is the intention of bash to recover from traps? Is there another solution with the same effect?

推荐答案

而不是

BASE=$(basename $FILE);

有这一个,而不是:

Have this one instead:

BASE=${FILE##*/}

这也是放置在后台的工作职能远离处理SIGINT接口是一个好主意。只要避免要求在它的输入。还引用您的变量总是正确的。

It's also a good idea to place your work functions on the background away from the interface that handles SIGINT. Just avoid asking for input within it. Also quote your variables properly always.

#!/bin/bash

# Register signal handler
ABORT=0;
trap ABORT=1 SIGINT;

# Create temp dir
TEMPDIR=$(mktemp -d -t $0);

# Helper functions
function do_other_stuff {
    true;
}

# Process files
for ((COUNTER = 0; COUNTER < 3 && ABORT == 0; COUNTER++)); do
    (
        FILE=/some/directory/$COUNTER.txt
        BASE=${FILE##*/}
        cp "$FILE" "$TEMPDIR"
        > "$FILE"
        do_other_stuff
        cp "$TEMPDIR/$BASE" "$FILE"
        rm "$TEMPDIR/$BASE"
    ) &
    CPID=$!
    # Handle SIGINT but don't end the loop until subprocess finishes its work.
    while kill -s 0 CPID &>/dev/null; do  ## Checks if subprocess is still there.
        # Wait if yes.
        wait "$CPID"
    done
done

rm -rf "$TEMPDIR"

这人会很快中止操作:

# Process files
for ((COUNTER = 0; COUNTER < 3 && ABORT == 0; COUNTER++)); do
    (
        FILE=/some/directory/$COUNTER.txt
        BASE=${FILE##*/}
        cp "$FILE" "$TEMPDIR"
        > "$FILE"
        do_other_stuff
        cp "$TEMPDIR/$BASE" "$FILE"
        rm "$TEMPDIR/$BASE"
    ) &
    CPID=$!
    while
        wait "$CPID"
        if [[ ABORT -eq 1 ]]; then
            kill -s ABRT "$CPID" &>/dev/null
            break
        fi
        kill -s 0 "$CPID" &>/dev/null
    do
        continue
    done
done

rm -rf "$TEMPDIR"

这篇关于bash的陷阱后恢复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆