加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在bash陷阱后恢复

发布时间:2020-12-16 01:57:56 所属栏目:安全 来源:网络整理
导读:我有一个带有一些文件操作的bash脚本,我想在按下CTRL C之后处理一个循环,直到块结束.我做了一个例子: #!/bin/bash# Register signal handlerABORT=0;trap ABORT=1 SIGINT;# Create temp dirTEMPDIR=$(mktemp -d -t $0);# Helper functionsfunction do_other
我有一个带有一些文件操作的bash脚本,我想在按下CTRL C之后处理一个循环,直到块结束.我做了一个例子:

#!/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在声明中

BASE=$(basename $FILE);

如果在basename命令期间发生陷阱,则不设置.这会导致cp和后续命令出错.

我错过了吗? bash的意图如何从陷阱中恢复?是否有其他解决方案具有相同的效果?

解决方法

代替

BASE=$(basename $FILE);

请改为:

BASE=${FILE##*/}

将工作函数放在远离处理SIGINT的接口的背景上也是一个好主意.只是避免在其中要求输入.还要始终正确引用变量.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读