从子shell退出整个bash脚本

如何解决从子shell退出整个bash脚本

我对bash脚本有点陌生,我有一个C ++程序通过一些命名管道与该bash脚本来回通信。我使用了inotifywait来监视文件夹中的新文件,并在添加文件(以.job结尾)时通过管道将其发送到。

我正在使用C ++程序将结果通过管道传递回去,如果结果为“退出”,则我希望bash脚本退出执行。

我试图通过出口1完成此操作,如下所示,但是这似乎并没有退出整个脚本。相反,在运行该出口之后,当我将另一个文件放入监视文件夹时,脚本结束。

我阅读了一些有关子外壳的信息,想知道这是否与它们有关,以及有关如何退出整个脚本的任何建议。

DROP_FOLDER="$1"
DATA_FOLDER="$2"
OUTPUT_FOLDER="$3"
PATH_TO_EXECS="./tmp/"
PATH_TO_COMPLETED="../completed/"

# create pipes
read_pipe=/tmp/c_to_bash
write_pipe=/tmp/bash_to_c

if [[ ! -p $read_pipe ]]; then
    mkfifo $read_pipe
fi

if [[ ! -p $write_pipe ]]; then
    mkfifo $write_pipe
fi

# start c++ program 
./tmp/v2 $DATA_FOLDER $OUTPUT_FOLDER $PATH_TO_EXECS "${write_pipe}" "${read_pipe}" &


# watch drop folder
inotifywait -m $DROP_FOLDER -e create -e moved_to |
    while read path action file; do
        # ends in .tga
        if [[ "$file" =~ .*tga$ ]]; then 

            # move to image dir
            mv "${DROP_FOLDER}${file}" "${DATA_FOLDER}${file}" 
        fi
        
        # ends in .job
        if [[ "$file" =~ .*job$ ]]; then
            # pipe to dispatcher 
            echo "${DROP_FOLDER}${file}" > $write_pipe

            # wait for result from pipe
            if read line <$read_pipe; then
                echo $line
                # check for quit result
                if [[ "$line" == 'quit' ]]; then
                    # move job file to completed
                    mv "${DROP_FOLDER}${file}" "${PATH_TO_COMPLETED}${file}"
                    # exit
                    exit 1
                fi

                # check for continue result
                if [[ "$line" == 'continue' ]]; then
                    # move job file to completed
                    mv "${DROP_FOLDER}${file}" "${PATH_TO_COMPLETED}${file}"
                fi
            fi
        fi
    done

解决方法

问题在于exit仅退出当前的子shell,在您的情况下,这是由于管道导致的while循环。

Bash仍然等待inotifywait退出,直到尝试写入另一个值并检测到管道已损坏,它才会执行。

要解决此问题,可以使用进程替代而不是管道:

while read path action file; do
...
done < <(inotifywait -m $DROP_FOLDER -e create -e moved_to)

之所以可行,是因为该循环未在子shell中执行,因此exit语句将退出整个脚本。另外,bash不会等待进程替换退出,因此它可能会一直挂到下一次尝试写入时,但不会停止脚本的退出。

,

通常,您可以在子shell中使用kill "$$"来终止主脚本($$会扩展到主shell的pid,即使在子shell中也可以,您可以设置{{ 1}}陷阱以捕获该信号。

但是看起来您实际上是想从右侧终止管道的左侧,即导致TERM终止,而不必等到向孤立管道写入内容并被{{1 }}。为此,您可以使用inotifywait明确地终止SIGPIPE进程:

inotifywait

pkill由父级选择; inotifywait -m /some/dir -e create,modify | while read path action file; do pkill -PIPE -P "$$" -x inotifywait done 应该是脚本的PID。这种解决方案当然不是万无一失的。还可以看看homebrew-tap

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?