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

标签 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 fine。

那么我在这里面临什么问题?

最佳答案

您的 bash 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 时,它会终止您的 session 。

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

关于linux - 为什么这种微小的变化会使 bash 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22430053/

相关文章:

linux - 如何在linux中检查 'if-then-else-fi'中的多个字符串?

linux - 通过脚本设置永久路径

java - 如何在同一终端中从我的 Java 应用程序打开 vi 编辑器?

linux - 我们可以使用 quilt 推送/添加到本地 git 存储库吗?

linux - 我如何从期望脚本中的文件中读取数据

Bash 读取输入 - Tab 提示符

bash - bash 中的简约 mysqldump 进度条

linux - 无法使 crontab 工作

linux - egrep 正则表达式 bash 脚本中的数字变量

linux - 用于搜索任何出现的短语并返回文件和路径列表的 Bash 命令