我有一个shell脚本,一次运行通常会运行近10分钟,但我需要知道在脚本实例已经运行时是否有另一个运行脚本的请求,新请求是否需要等待现有要复制的实例或将启动一个新实例。
每当请求可用于同一个脚本时,我都需要启动一个新实例。
怎么做......
shell脚本是一个轮询脚本,它在目录中查找文件并执行文件。文件的执行需要将近10分钟或更长时间。但是在执行期间如果新文件到达,则还必须执行同时进行。
下面是shell脚本,以及如何修改它以执行多个请求..
#!/bin/bash
while [ 1 ]; do
newfiles=`find /afs/rch/usr8/fsptools/WWW/cgi-bin/upload/ -newer /afs/rch/usr$
touch /afs/rch/usr8/fsptools/WWW/cgi-bin/upload/.my_marker
if [ -n "$newfiles" ]; then
echo "found files $newfiles"
name2=`ls /afs/rch/usr8/fsptools/WWW/cgi-bin/upload/ -Art |tail -n 2 |head $
echo " $name2 "
mkdir -p -m 0755 /afs/rch/usr8/fsptools/WWW/dumpspace/$name2
name1="/afs/rch/usr8/fsptools/WWW/dumpspace/fipsdumputils/fipsdumputil -e -$
$name1
touch /afs/rch/usr8/fsptools/WWW/dumpspace/tempfiles/$name2
fi
sleep 5
done
答案 0 :(得分:2)
在编写与您描述的脚本类似的脚本时,我采用两种方法之一。
首先,您可以使用pid文件指示不应运行第二个副本。例如:
#!/bin/sh
pidfile=/var/run/$(0##*/).pid
# remove pid if we exit normally or are terminated
trap "rm -f $pidfile" 0 1 3 15
# Write the pid as a symlink
if ! ln -s "pid=$$" "$pidfile"; then
echo "Already running. Exiting." >&2
exit 0
fi
# Do your stuff
我喜欢使用符号链接来存储pid,因为编写符号链接是一个原子操作;两个进程不能相互冲突。您甚至不需要检查pid符号链接是否存在,因为ln
的失败清楚地表明无法设置pid。这可能是权限或路径问题,也可能是因为符号链接已经存在。
第二个选项是使它成为可能..不,更可取..不阻止其他实例,而是配置此脚本所做的任何事情,以允许多个服务器同时在不同的队列条目上运行。 " 单队列单服务器"永远不会像" 单队列多服务器"。既然你没有在你的问题中包含代码,我无法知道这种方法对你有用,但这里有一些解释性的元bash:
#!/usr/bin/env bash
workdir=/var/tmp # Set a better $workdir than this.
a=( $(get_list_of_queue_ids) ) # A command? A function? Up to you.
for qid in "${a[@]}"; do
# Set a "lock" for this item .. or don't, and move on.
if ! ln -s "pid=$$" $workdir/$qid.working; then
continue
fi
# Do your stuff with just this $qid.
...
# And finally, clean up after ourselves
remove_qid_from_queue $qid
rm $workdir/$qid.working
done
这样做的结果是一次转移一个"的概念。从处理程序到数据。如果您有多CPU系统,则可能有足够的容量同时处理多个队列条目。
答案 1 :(得分:1)
ghoti's answer显示了一些有用的技巧,如果修改脚本是一个选项。
一般来说,对于现有的脚本:
除非您确切知道:
该脚本除了输出到终端或写入具有shell实例特定名称的文件(例如将当前shell的PID $$
合并到之外)之外没有任何副作用文件名)或其他一些特定于实例的位置,
或者说脚本是为并行执行而明确设计的,
我认为你不能安全地同时运行脚本的多个副本。
期望将平均shell脚本设计为并发使用 。
答案 2 :(得分:0)
从操作系统的角度来看,几个进程当然可以并行执行相同的程序。不用担心这个。
然而,是可以想象的,当一个(粗心)程序员并行执行两个副本时,它会以一种产生错误结果的方式编写程序。