2012-06-05 2 views
4
echo bla | awk 'BEGIN{fname="foo.txt"} {print $0 >>fname; print "rm -f " fname | "/usr/bin/ksh"; close("/usr/bin/ksh"); print $0 >>fname}' 

После выполнения этой команды в итоге я должен получить файл «foo.txt», правильно?Awk не может воссоздать удаленный файл?

Не работает. Я попробовал систему («/ usr/bin/rm -f» fname), чтобы удалить файл, bash вместо ksh, Linux, HP-UX, Cygwin, fflush («»), ... просто не работает! Кажется, что после удаления файла Awk просто не может писать в файл с тем же именем.

Похож на ошибку в Awk, или я что-то упускаю (большое время!)?!

ответ

5

awk сохраняет файл открытым. Попробуйте закрыть его:

echo bla | awk 'BEGIN{fname="foo.txt"} 
{ 
    print $0 >>fname 
    print "rm -f " fname | "/usr/bin/ksh" 
    close("/usr/bin/ksh") 
    close(fname) 
    print $0 >>fname 
}' 

awk открывает файл при первом входе в файл и сохраняет этот файл открытым. Когда ссылка удалена из файловой системы, awk по-прежнему открывает файл, поэтому он не использует имя «foo.txt» для доступа к нему. Закрывая файл, вы заставляете awk снова смотреть на файловую систему и создавать теперь несуществующую ссылку «foo.txt».

Для удобства читателей, которые не понимают различия между ссылкой и файлом, попробуйте следующее:

$ rm -rf /tmp/foo; mkdir /tmp/foo; cd /tmp/foo # start with a clean directory 
$ touch foo.txt; ln foo.txt bar.txt    # Create a file with two links 
$ # run original awk script (without closing the file) 
$ cat bar.txt 

Вы увидите линию «ли» дважды в bar.txt. Причина в том, что bar.txt и foo.txt являются ссылками на один и тот же файл. awk открывает этот файл и записывает в него строку, затем удаляет ссылку foo.txt, затем записывает другую строку в файл. Когда awk завершается, ссылка foo.txt была удалена, но файл по-прежнему доступен и доступен по ссылке bar.txt. Если bar.txt удаляется, то файловая система заметит, что количество ссылок для файла упало до нуля, и файл будет удален.

+0

Позор на меня. Вы абсолютно правы. Большое спасибо. – ExpertNoob

Смежные вопросы