shell - 根据条件无限循环运行具有 While 条件的 shell 脚本

标签 shell if-statement for-loop while-loop conditional-statements

我需要创建一个 shell 脚本,根据从目录 中的 shell 脚本收到的请求标志,将一些指标/标志文件放置在 /dir1/dir2/flag_file_directory 目录中/dir1/dir2/req_flag_file_directory 和目录中存在的源文件为 dir1/dir2/source_file_directory。为此,我需要在无限循环中使用 while 条件运行脚本,因为我不知道源文件何时可用。

所以,我的实现计划有点像这样 - 假设计划在早上某个时间运行的 JOB1 将首先放置(触摸)一个请求标志(例如 touch/dir1/dir2/req_flag_file_directory/req1.req),表示该作业正在运行,因此在源文件目录中查找模式 file_pattern_YYYYMMDD.CSV 的源文件(不同作业的文件模式不同) ,如果存在,则数数。如果文件计数正确,则首先删除该作业的请求标志,然后触摸/dir1/dir2/flag_file_directory中的指示器/标志文件。然后,该指示器/标志文件将用作源文件全部存在的指示器,并且可以继续将这些文件加载​​到我们的系统中。

我将在一个文件中包含与作业及其标志文件相关的所有详细信息,其结构如下所示。根据请求标志,脚本应该知道在放置指标文件之前应该查找哪些其他标准:

request_flags|source_name|job_name|file_pattern|file_count|indicator_flag_file
req1.req|Sourcename1|jobname1|file_pattern_1|3|ind1.ind
req2.req|Sourcename2|jobname2|file_pattern_2|6|ind2.ind
req3.req|Sourcename3|jobname3|file_pattern_3|1|ind3.ind
req**n**.req|Sourcename**n**|jobname**n**|file_pattern_**n**|2|ind**n**.ind

请告诉我如何实现这一目标,以及您是否还有其他建议或解决方案

最佳答案

您可以使用文件锁定和命名管道来创建事件队列,而不是让服务守护程序脚本在无限循环中进行轮询(即定期唤醒以检查它是否需要工作)。

服务守护进程 daemon.sh 的概述。该脚本将无限循环,通过从读取行处的命名管道读取数据来阻塞,直到消息到达(即,某个其他进程写入$RequestPipe)。

#!/bin/bash
#   daemon.sh

LockDir="/dir1/dir2/req_flag_file_directory"
LockFile="${LockDir}/.MultipleWriterLock"
RequestPipe="${LockDir}/.RequestQueue"

while true ; do

    if read line < "$RequestPipe" ; then
        # ... commands to be executed after message received ...
        echo "$line"            # for example
    fi

done



requestor.sh 的概述,该脚本在一切准备就绪时唤醒服务守护进程。该脚本完成了所有必要的准备工作,例如在 req_flag_file_directorysource_file_directory 中创建文件,然后通过写入命名管道来唤醒服务守护程序脚本。它甚至可以发送一条包含服务守护程序更多信息的消息,例如“作业 1 就绪”。

#!/bin/bash
#   requestor.sh

LockDir="/dir1/dir2/req_flag_file_directory"
LockFile="${LockDir}/.MultipleWriterLock"
RequestPipe="${LockDir}/.RequestQueue"

# ... create all the necessary files ...

(
    flock --exclusive 200
    #   Unblock the service daemon/listener by sending a line of text.
    echo Wake up sleepyhead. > "$RequestPipe"
) 200>"$LockFile"       # subshell exit releases lock automatically



daemon.sh 充实了一些错误处理:

#!/bin/bash
#   daemon.sh

LockDir="/dir1/dir2/req_flag_file_directory"
LockFile="${LockDir}/.MultipleWriterLock"
RequestPipe="${LockDir}/.RequestQueue"
SharedGroup=$(echo need to put a group here 1>&2; exit 1)


#
if [[ ! -w "$RequestPipe" ]] ; then
    #    Handle 1st time. Or fix a problem.
    mkfifo --mode=775 "$RequestPipe"
    chgrp "$SharedGroup" "$RequestPipe"
    if [[ ! -w "$RequestPipe" ]] ; then
        echo "ERROR: request queue, can't write to $RequestPipe" 1>&2
        exit 1
    fi
fi

while true ; do

    if read line < "$RequestPipe" ; then
        # ... commands to be executed after message received ...
        echo "$line"        # for example
    fi

done



requestor.sh 充实了一些错误处理:

#!/bin/bash
#   requestor.sh

LockDir="/dir1/dir2/req_flag_file_directory"
LockFile="${LockDir}/.MultipleWriterLock"
RequestPipe="${LockDir}/.RequestQueue"
SharedGroup=$(echo need to put a group here 1>&2; exit 1)

# ... create all the necessary files ...

#
if [[ ! -w "$LockFile" ]] ; then
    #    Handle 1st time. Or fix a problem.
    touch "$LockFile"
    chgrp "$SharedGroup" "$LockFile"
    chmod 775 "$LockFile"
    if [[ ! -w "$LockFile" ]] ; then
        echo "ERROR: write lock, can't write to $LockFile" 1>&2
        exit 1
    fi
fi
if [[ ! -w "$RequestPipe" ]] ; then
    #    Handle 1st time. Or fix a problem.
    mkfifo --mode=775 "$RequestPipe"
    chgrp "$SharedGroup" "$RequestPipe"
    if [[ ! -w "$RequestPipe" ]] ; then
        echo "ERROR: request queue, can't write to $RequestPipe" 1>&2
        exit 1
    fi
fi

(
    flock --exclusive 200 || {
        echo "ERROR: write lock, $LockFile flock failed." 1>&2
        exit 1
    }
    #   Unblock the service daemon/listener by sending a line of text.
    echo Wake up sleepyhead. > "$RequestPipe"

) 200> "$LockFile"      # subshell exit releases lock automatically

关于shell - 根据条件无限循环运行具有 While 条件的 shell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23303299/

相关文章:

c++ - 当一个功能完成另一个功能打开时我该怎么办?

Java 循环结构,可迭代字符串并使用多个变量

python - 如何并行遍历两个列表?

linux - 我如何重命名具有不同扩展名的文件夹中的前 5 个文件,同时保持旧文件相同?

bash - 停止处理源文件并继续

bash - 为什么通配符在 `sudo rm` 语句中不起作用?

html - 如何检查用户输入的值是否具有特定数字?

excel - Vlookup 包含其他单元格一部分的单元格,但不是那么简单

windows - 将终端区域设置永久设置为 C.UTF8

Python - 所有循环中的 `break`