convenientstore has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to run a perl program against file which has hard link to another file.
I thought I could do below and change both but I cannot and both file is getting emptied out
Is this my lack of unix or perl?
~/script/perl/temp@myserver >ls -li done.txt* 35466 -rw-rw-r-- 2 xmen xmen 54 Aug 7 17:51 done.t +xt 35467 -rw-rw-r-- 1 xmen xmen 0 Aug 7 17:51 done.tx +t2 35466 -rw-rw-r-- 2 xmen xmen 54 Aug 7 17:51 done.t +xt_ln ~/script/perl/temp@myserver >cat done.txt yahoo never yahoo never never never yahoo yahoo yahoo ~/script/perl/temp@myserver >cat done.txt_ln yahoo never yahoo never never never yahoo yahoo yahoo ~/script/perl/temp@myserver >cat perl.file #!/usr/bin/perl -w use strict; open(FH,'done.txt'); while (<FH>) { s/yahoo/never/g; print; } close(FH); ~/script/perl/temp@myserver >./perl.file done.txt > done.txt_ln ~/script/perl/temp@myserver >ls -li done.txt* 35466 -rw-rw-r-- 2 xmen xmen 0 Aug 7 17:56 done.txt 35467 -rw-rw-r-- 1 xmen xmen 0 Aug 7 17:51 done. +txt2 35466 -rw-rw-r-- 2 xmen xmen 0 Aug 7 17:56 done.t +xt_ln

Replies are listed 'Best First'.
Re: file input output problem
by johngg (Canon) on Aug 07, 2007 at 22:40 UTC
    against file which has hard link to another file

    You actually only have one file on disk (uniquely identified by the device and inode values, see stat and lstat) with, in effect, two references to it in the directory table. You can have multiple hard links all pointing to the same file if you like. Any change to one will appear in all of them. However, deleting one of them will leave the others in place.

    $ echo "hello world" > xxyyzz $ ln xxyyzz aabbcc $ ln xxyyzz ddeeff $ ls -li aabbcc ddeeff xxyyzz 45063 -rw-r--r-- 3 root root 12 Aug 7 23:36 aabbc +c 45063 -rw-r--r-- 3 root root 12 Aug 7 23:36 ddeef +f 45063 -rw-r--r-- 3 root root 12 Aug 7 23:36 xxyyz +z $ cat aabbcc hello world $ echo bye >> ddeeff $ cat xxyyzz hello world bye $ rm aabbcc $ ls -li aabbcc ddeeff xxyyzz aabbcc: No such file or directory 45063 -rw-r--r-- 2 root root 16 Aug 7 23:38 ddeef +f 45063 -rw-r--r-- 2 root root 16 Aug 7 23:38 xxyyz +z $

    I hope this helps you.

    Cheers,

    JohnGG

      so bascially, my only option is
      ./perl.file done.txt > done.temp
      and then
      cat done.temp > done.txt
        If the file is relatively small you could just read all of it into memory and then overwrite the file after you have made your changes.
        #!/usr/bin/perl use strict; use warnings; my @contents; my $file = 'done.txt'; open IN, '<', $file or die "Could not open $file for reading."; while (<IN>) { $_ =~ s/yahoo/never/g; push @contents, $_; } close IN or die "Could not close $file after reading."; open OUT, '>', $file or die "Could not open $file for writing."; foreach my $line ( @contents ) { print OUT $line or die "Failed to write to $file ($line)." } close OUT or die "Could not close $file after writing.";
Re: file input output problem
by mamawe (Sexton) on Aug 07, 2007 at 22:11 UTC
    When you redirect output to done.txt_ln the shell opens and truncates this file which happens to be the same as done.txt.

    At the time your script sees this file it is already truncated.