我需要创建一个 shell 脚本,根据从目录 中的 shell 脚本收到的请求标志,将一些指标/标志文件放置在
和目录中存在的源文件为 /dir1/dir2/flag_file_directory
目录中/dir1/dir2/req_flag_file_directorydir1/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_directory
和 source_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/