为什么这种微小的变化会使bash崩溃?

时间:2014-03-15 21:36:12

标签: linux bash shell

我一直在玩一个脚本,该脚本使用“二进制”方法来查找目录中的.txt文件数。该脚本可选择猜测($ 1)作为出发点。

名为“search.sh”的脚本大多是简单的数学:

#!/bin/bash

set_SEARCH()
{
    DIVIDED=$SEARCH
    SEARCH=$(($SEARCH * 2))
}

increase_SEARCH()
{
    SEARCH=$(($SEARCH + $DIVIDED))
    DIVIDED=$(($DIVIDED / 2))
    #echo $DIVIDED
}

decrease_SEARCH()
{
    SEARCH=$(($SEARCH - $DIVIDED))
    DIVIDED=$(($DIVIDED / 2))
    #echo $DIVIDED
}

test_SEARCH()
{
    while [ -f "$(($SEARCH * 2)).txt" ]
    do
        set_SEARCH
    done
    if [ -f "${SEARCH}.txt" ]
    then
        #echo "Trying $SEARCH"
        if [ "$DIVIDED" = 0 ]
        then
            NUMBER=$(($SEARCH + 0))
            echo "export NUMBMER=$NUMBER"
            exit
        fi
        increase_SEARCH
        test_SEARCH
    else
        #echo "Trying $SEARCH"
        if [ "$DIVIDED" = 0 ]
        then
            NUMBER=$(($SEARCH - 1))
            echo "export NUMBMER=$NUMBER"
            exit
        fi
        decrease_SEARCH
        test_SEARCH
    fi 
}

SEARCH=2
while   [[ "$SEARCH" -le "$1" ]] ;
do
    SEARCH=$(($SEARCH * 2))
done
DIVIDED=$(($SEARCH / 2))

test_SEARCH

为了测试脚本中所有文件编号和1到1000之间的猜测,我使用以下命令:

 rm *.txt ;for textfile in {1..1000} ; do touch $textfile.txt ; for guess in {1..1000} ; do eval $(./search.sh $guess) ; if [ $NUMBMER  != "$(($(ls|wc -l) - 1))" ] ; then echo "Script failed $textfile $guess $NUMBMER" ; exit ; else echo $textfile $guess; fi ; done ; done

这没关系,但是使用{4..1000}更改第一个括号的内容会导致我的Ubuntu 12.04 Bash shell崩溃。该命令循环通过4号罚款。

那么我面临的问题是什么?

1 个答案:

答案 0 :(得分:2)

你抨击shell并没有崩溃,它只是做你告诉它做的事情。看一下你直接在shell上运行的命令(为了便于阅读,我重写了它)

rm *.txt                                                                              

for textfile in {1..1000} ; do                                                            |    SEARCH=$(($SEARCH + $DIVIDED))
    touch $textfile.txt                                                                   |    DIVIDED=$(($DIVIDED / 2))
    for guess in {1..1000}; do                                                            |    #echo $DIVIDED
        eval $(./search.sh $guess) <-- script run as subprocess                                                      |}
        if [ $NUMBMER  != "$(($(ls|wc -l) - 1))" ]; then                                  |
            echo "Script failed $textfile $guess $NUMBMER"                                |decrease_SEARCH()

            exit <---- this is terminating your shell                                                                        |{
        else                                                                              |    SEARCH=$(($SEARCH - $DIVIDED))
            echo $textfile $guess                                                         |    DIVIDED=$(($DIVIDED / 2))
        fi                                                                                |    #echo $DIVIDED
    done                                                                                  |}
done

当您调用bash脚本时,它将作为子进程运行,因此,如果在脚本中调用exit,则只需终止子进程。

当您直接从提示符运行命令时,它不会作为子进程运行,因此当调用exit时,它会终止您的会话。

因此,只需从提示中运行的命令中删除exit即可继续。