【发布时间】:2015-02-10 17:00:46
【问题描述】:
我在 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} 移动到一个文件夹(假设它是“存档”文件夹)。 ${filename} 应该引用参数,并为每次执行调用提供唯一的文件名,并且始终具有“.txt”扩展名。
问题是:如果同时有3个(或更多)脚本执行,结果会是:
一次执行将产生正确的顺序
其他执行会导致
mv ${param}/*.txt ${param}/archive在awk 'FNR-1' ${listoffiles} >> ${param}/${filename}之前先执行
我在这里做错了什么?或者有什么方法可以保证脚本严格执行它的步骤? (我尝试添加&& 或; 但结果保持不变)
【问题讨论】:
-
Shell 脚本在使用空格时需要非常精确。赋值必须在等号两边都没有空格。这意味着
awk脚本没有文件要处理。学习使用bash -x(和/或sh -x)进行调试。即使您修复了这个问题,当它来自扩展${listoffiles}时,shell 也不会扩展或 glob$param/*.txt。 -
@JonathanLeffler, ...它不会进行扩展,可以肯定的是,但它为什么不进行 glob(如果引用样式已更正以便可以执行扩展) ?这根本不是说我在为该代码辩护。将 glob 表达式存储在标量变量中当然是可恶的。
-
@CharlesDuffy:哦——你是对的。如果 cmets 可以编辑更长时间,我会修复它。如果
$param在$listoffiles之外处理(例如listoffiles='*.txt'; echo "$param"/$listoffiles),则会发生通配。如果您有一个名为$param的目录(而不是$param的扩展),则会发生通配。基本上,您必须认真考虑 shell 处理expansions 的方式。 -
@Kioels,这也不是好的做法。见mywiki.wooledge.org/ParsingLs
-
您描述的症状是完全如果
param在多个解释之间是相同的,那么人们会期望什么,如果不是,则完全无法解释。 (并不是任何给定的实例都在乱序运行命令,而是实例 A 正在重命名文件,而实例 B 正在创建它们)。