我在AIX 7.1中编写了shell脚本,但它没有以正确的顺序执行。
shell脚本是
receive 2 parameter $param and $filename
listoffiles='ls ${param}/*.txt'
awk 'FNR-1' ${listoffiles} >> ${param}/${filename}
mv ${param}/*.txt ${param}/archive
我的目标是将${listoffiles}
中的行合并到一个文件中,不包括每个文件的标题。
之后,我想将${listoffiles}
个文件,包括生成的$ {param} / $ {filename}文件移到一个文件夹中(让我们说它' s"存档&# 34;文件夹)。 $ {filename}应引用参数,并为每次执行调用提供文件唯一名称,并且始终具有" .txt"扩展
问题是:如果同时执行3个(或更多)脚本,结果将是:
一次执行将产生正确的订单
其他执行将导致mv ${param}/*.txt ${param}/archive
首先执行awk 'FNR-1' ${listoffiles} >> ${param}/${filename}
我在这里做错了什么?或者有什么方法可以保证脚本严格执行它的执行步骤? (我已尝试添加&&
或;
,但结果保持不变)
答案 0 :(得分:2)
不要对combine.txt
等名称进行硬编码;相反,使用mktemp
为您的实例创建一个唯一的临时文件:
tempfile=$(mktemp "$param/combine.XXXXXX")
awk 'FNR-1' "$param"/*.txt >"$tempfile"
mv "$tempfile" "$param/archive"
使用唯一文件名将允许脚本的并发实例在不相互交互的情况下运行。
答案 1 :(得分:0)
由于您首先收集文件列表,然后对其进行处理,因此当它处理文件时,该文件可能已被另一个进程移动。
您可能想尝试锁定文件 - 请参阅How to prevent a script from running simultaneously? - 指定与您要处理的文件相关的文件名,并给它一个短暂的超时。如果另一个进程做了同样的事情,它将失败。你可以跳过这一个,因为另一个线程正在处理它。
还要确保(正如@Charles Duffy正确指出的那样)每个进程都会写入不同的文件。