awk 可以跳过不存在的文件吗?
Posted
技术标签:
【中文标题】awk 可以跳过不存在的文件吗?【英文标题】:Can awk skip files which do not exist, race-free? 【发布时间】:2010-09-18 01:09:54 【问题描述】:有没有办法让 awk (gawk) 忽略或跳过丢失的文件?也就是说,通过命令行传递的文件不再存在于文件系统中(例如 /proc/[1-9]* 下快速出现/消失的文件)。
默认情况下,丢失文件是致命错误:-(
我希望能够做类似这样的事情:
BEGIN MISSING_FILES_ARE_FATAL = 0 # <- Wishful thinking!
count++
END print count
包装脚本无法在 awk 运行之前检查文件是否存在,因为它们可能会在检查它们和 awk 尝试打开它们之间消失,即,这是一个竞争条件。 (在awk中check-then-open也是一种竞争条件,虽然时间比较紧)
【问题讨论】:
【参考方案1】:GAWK 4 有BEGINFILE
,您可以在其中测试ERRNO
,如果ERRNO
不为空(表示文件无法打开),则执行nextfile
。
【讨论】:
【参考方案2】:即使在你的 awk 脚本周围加上一个 perl 或 shell 包装器,我认为仍然会有竞争条件。例如,使用 ADEpt 的其他很好的 shell sn-p:
[ -r "$filename" ] && awk -f ... $filename
没有什么可以阻止进程在 -r 和 awk 尝试打开文件之间消失...
我能想到的唯一答案是使用 LD_PRELOAD 代替 awk 的系统打开调用,这样如果文件丢失,则打开 /dev/null 上的读取文件描述符。
这可能行得通...
【讨论】:
【参考方案3】:你可以通过系统调用检查ARGV
的内容,然后通过getline
处理它们。
if (system("test -r " ARGV[1]) == 0)
while ( (getline aline < ARGV[1]) >0 )
# process ARGV[1] via `aline` instead of $0
...
然后处理ARGV[2]等 高温
【讨论】:
【参考方案4】:在我看来,“MISSING_FILES_ARE_FATAL = 0”功能将成为下一个 gawk 版本的一部分。查看当前 gawk-stable 源代码的 ChangeLog 文件:
--- 剪断 ---
2008 年 8 月 22 日星期五 14:43:49 Arnold D. Robbins
* io.c (nextfile): Users Strong In The Ways Of The Source can use
non-existant files on the command line without it being a fatal error.
--- 剪断 ---
http://cvs.savannah.gnu.org/viewvc/gawk-stable/ChangeLog?revision=1.87&root=gawk&view=markup
赫尔曼
【讨论】:
【参考方案5】:按照最好的传统,我将使用 Perl 程序回答您的 awk 问题。
#!/usr/bin/perl -w
for my $file (@ARGV)
open my $fh, $file or next;
while(<$fh>)
...do your thing here...
(这不是 awk,但它是唯一没有竞争条件的解决方案。)
【讨论】:
【参考方案6】:哦,对不起。忽略我之前的回答。这是另一个建议:
cat /proc/[1-9]* 2>/dev/null | awk ....
Cat 会吞噬所有文件,无论是丢失的还是现有的,cat 的错误都会被遗忘(丢失的文件对 cat 来说是非致命错误),并且 awk 将能够处理结果。
【讨论】:
以上是关于awk 可以跳过不存在的文件吗?的主要内容,如果未能解决你的问题,请参考以下文章
shell 判断PID是不是存在,存在则kill掉,不存在则跳过