unix中将4个shell脚本依次同步到运行
Synchronizing four shell scripts to run one after another in unix
我有 4 个 shell 脚本来生成一个文件(比方说 param.txt),该文件被另一个工具(informatica)使用,当该工具完成处理时,它会删除 param.txt.
这里的目的是可以在不同的时间调用所有四个脚本让我们说 12:10 am,12:13 am,12:16 am,12:17 am。第一个脚本在 12:10am 运行并创建 param.txt 并触发使用 param.txt 的 informatica 进程。 Informatica 进程还需要 5-10 分钟才能完成并删除 param.txt。第二个脚本在 12:13 am 调用并等待 param.txt 不可用,当 informatica 进程删除它时,脚本 2 创建新的 param.txt 并再次触发相同的 informatica。另外 2 个脚本也会发生同样的情况。
我在所有 4 个 shell 脚本中使用 Until 和 sleep 命令来检查 param.txt 的不可用性,如下所示:
until [ ! -f "$paramfile" ]
do
Sleep 10
done
<create param.txt file>
这里的问题是,有时当所有 4 个脚本开始时,第一个成功并生成 param.txt(因为之前没有 param.txt)和其他等待,但是当 informatica 进程完成并删除 param.txt,其余 3 个脚本或其中 2 个同时检查不可用性,其中一个创建它但都成功。我检查了四个脚本之间不同的休眠间隔组合,但几乎每次都会出现这种情况。
您正在经历典型的竞争条件。要解决此问题,您需要在 4 个脚本之间共享 "lock"(或类似的)。
有几种方法可以实现这一点。在 bash 中执行此操作的一种方法是使用 flock
命令,并将商定的文件名用作锁定。 flock man page 有一些类似这样的用法示例:
(
flock -x 200 # try to acquire an exclusive lock on the file
# do whatever check you want. You are guaranteed to be the only one
# holding the lock
if [ -f "$paramfile" ]; then
# do something
fi
) 200>/tmp/lock-life-for-all-scripts
# The lock is automatically released when the above block is exited
你也可以要求flock
在无法获取锁的情况下立即失败,或者在超时后失败(例如打印"still trying to acquire the lock"并重新启动)。
根据您的用例,您还可以锁定 'informatica' 二进制文件(在这种情况下一定要使用 200<
,以打开文件进行读取而不是(结束)写作)
您可以使用 GNU Parallel 作为计数信号量或互斥量,方法是将其作为 sem
而不是 parallel
调用。向下滚动到 this page 上的 Mutex
。
因此,您可以使用:
sem --id myGlobalId 'create input file; run informatica'
sem --id myGlobalId 'create input file; run informatica'
sem --id myGlobalId 'create input file; run informatica'
sem --id myGlobalId 'create input file; run informatica'
注意我已经指定了全局 id
以防您 运行 来自不同终端或 cron 的作业。如果您从一个终端启动所有作业,则没有必要这样做。
感谢您的宝贵建议。它确实帮助我从另一个维度思考。但是我没有提到我正在使用 Solaris UNIX,但我找不到与 flock 等效或类似的功能。我本可以要求团队安装一个实用程序,但与此同时我找到了解决此问题的方法。
我了解到 mkdir 函数本质上是原子的,而 'touch' 创建文件的命令不是(仍然没有完整的解释它是如何工作的)。这意味着一次只有 1 个脚本可以 create/delete 目录 'lockdir' 4 个中,其他 3 个必须等待。
while true;
do
if mkdir "$lockdir"; then
< create param file >
break;
fi
Sleep 30
done
我有 4 个 shell 脚本来生成一个文件(比方说 param.txt),该文件被另一个工具(informatica)使用,当该工具完成处理时,它会删除 param.txt.
这里的目的是可以在不同的时间调用所有四个脚本让我们说 12:10 am,12:13 am,12:16 am,12:17 am。第一个脚本在 12:10am 运行并创建 param.txt 并触发使用 param.txt 的 informatica 进程。 Informatica 进程还需要 5-10 分钟才能完成并删除 param.txt。第二个脚本在 12:13 am 调用并等待 param.txt 不可用,当 informatica 进程删除它时,脚本 2 创建新的 param.txt 并再次触发相同的 informatica。另外 2 个脚本也会发生同样的情况。
我在所有 4 个 shell 脚本中使用 Until 和 sleep 命令来检查 param.txt 的不可用性,如下所示:
until [ ! -f "$paramfile" ]
do
Sleep 10
done
<create param.txt file>
这里的问题是,有时当所有 4 个脚本开始时,第一个成功并生成 param.txt(因为之前没有 param.txt)和其他等待,但是当 informatica 进程完成并删除 param.txt,其余 3 个脚本或其中 2 个同时检查不可用性,其中一个创建它但都成功。我检查了四个脚本之间不同的休眠间隔组合,但几乎每次都会出现这种情况。
您正在经历典型的竞争条件。要解决此问题,您需要在 4 个脚本之间共享 "lock"(或类似的)。
有几种方法可以实现这一点。在 bash 中执行此操作的一种方法是使用 flock
命令,并将商定的文件名用作锁定。 flock man page 有一些类似这样的用法示例:
(
flock -x 200 # try to acquire an exclusive lock on the file
# do whatever check you want. You are guaranteed to be the only one
# holding the lock
if [ -f "$paramfile" ]; then
# do something
fi
) 200>/tmp/lock-life-for-all-scripts
# The lock is automatically released when the above block is exited
你也可以要求flock
在无法获取锁的情况下立即失败,或者在超时后失败(例如打印"still trying to acquire the lock"并重新启动)。
根据您的用例,您还可以锁定 'informatica' 二进制文件(在这种情况下一定要使用 200<
,以打开文件进行读取而不是(结束)写作)
您可以使用 GNU Parallel 作为计数信号量或互斥量,方法是将其作为 sem
而不是 parallel
调用。向下滚动到 this page 上的 Mutex
。
因此,您可以使用:
sem --id myGlobalId 'create input file; run informatica'
sem --id myGlobalId 'create input file; run informatica'
sem --id myGlobalId 'create input file; run informatica'
sem --id myGlobalId 'create input file; run informatica'
注意我已经指定了全局 id
以防您 运行 来自不同终端或 cron 的作业。如果您从一个终端启动所有作业,则没有必要这样做。
感谢您的宝贵建议。它确实帮助我从另一个维度思考。但是我没有提到我正在使用 Solaris UNIX,但我找不到与 flock 等效或类似的功能。我本可以要求团队安装一个实用程序,但与此同时我找到了解决此问题的方法。
我了解到 mkdir 函数本质上是原子的,而 'touch' 创建文件的命令不是(仍然没有完整的解释它是如何工作的)。这意味着一次只有 1 个脚本可以 create/delete 目录 'lockdir' 4 个中,其他 3 个必须等待。
while true;
do
if mkdir "$lockdir"; then
< create param file >
break;
fi
Sleep 30
done