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」で終わるはずですよね?

動作しません。system( "/ usr / bin / rm -f" fname)でファイルを削除しようとしましたが、kshの代わりにbash、Linux、HP-UX、Cygwin、fflush( "")、...動作しません!ファイルが削除された後、Awkは同じ名前のファイルに書き込むことができなくなったようです。

Awkのバグのように見えますか、それとも何かが足りないのでしょうか(大きな時間です!)?!

4

1 に答える 1

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に「bla」という行が2回表示されます。その理由は、bar.txtfoo.txtが両方とも同じファイルへのリンクであるためです。 awkそのファイルを開いて行を書き込み、foo.txt次にリンクを削除してから、ファイルに別の行を書き込みます。awk終了すると、リンクはfoo.txt削除されますが、ファイルはまだそこにあり、リンクを介してアクセスできますbar.txt。が削除されると、ファイルシステムはファイルのリンク数がゼロになったことを認識し、ファイルbar.txtが削除されます。

于 2012-06-05T12:48:20.083 に答える