首页 > 解决方案 > BASH 脚本在 EXIT 命令之后继续

问题描述

这是一个更大的 bash (Fedora 30) 脚本的一部分示例,它显示了我遇到的问题

该脚本应该遍历目录树并在找到任何超过 103 个字符的文件名时退出。

SS_NORMAL=0
JOLIET_MAX=103
MD5FILE=/tmp/blah.md5

function myExit
{
    echo Exiting $1 ...
    exit
}

function traverse
{
    find . -type f -print0 | 
       while IFS= read -r -d '' MD5_FILESPEC; do
          MD5_BASE=$(basename "$MD5_FILESPEC")
          if [ "${#MD5_BASE}" -gt "$JOLIET_MAX" ]; then
              myExit "[FAIL] Filename size ${#MD5_BASE} too long - $MD5_FILESPEC"
           fi
       done
}

traverse
date; date; date

在找到这些长文件名之一之前,它工作正常。它调用 myExit 并退出循环,但并非完全退出脚本。我总是在输出末尾看到三个日期,但我不应该看到。

我该如何处理?

标签: bash

解决方案


解决循环在子进程中运行的问题的一种简单方法while是进行逆转:while在同一个 shell 中运行,这是一个生成文件的子进程。

find但是,如果文件名的接收者必须在操作员的右边,我们怎么能做到这一点|呢?答案是在 GNU Bash 中,我们有一个名为“进程替换”的语言扩展。

进程替换是一种语法,Bash 将其转换为一些看起来和行为类似于文件名的字符串,并以这种方式被命令接受。当程序打开并读取该文件(或者,在另一个方向,写入它)时,它通过管道与另一个进程进行通信。

构思草图:

   while IFS= read -r -d '' MD5_FILESPEC; do
      MD5_BASE=$(basename "$MD5_FILESPEC")
      if [ "${#MD5_BASE}" -gt "$JOLIET_MAX" ]; then
          myExit "[FAIL] Filename size ${#MD5_BASE} too long - $MD5_FILESPEC"
       fi
   done < <(find . -type f -print0)
   #      ^^^^^^^^^^^^^^^^^^^^^^^^^ this is the process substitution

推荐阅读