in reply to Re: Deleting a file after it runs?
in thread Deleting a file after it runs?

    The removal is completed and disk space released once your program closes.
I believe the removal is happening even earlier -- after the program has compiled, and the Perl interpreter has started executing it, but potentially long before the program completes.  Try this to see what I mean:
#!/usr/bin/perl -w + # Strict use strict; use warnings; + # Main program print "Check file before unlink\n"; sleep 1; system("ls $0"); print "Unlinking the file $0\n"; sleep 1; unlink $0; print "Check file after unlink\n"; sleep 1; system("ls $0"); + print "File should be now be gone from disk (but still in memory)\n"; print "Try ^Z and check it with 'ls $0' ... (come back with 'fg')\n"; sleep 10; + print "I'm still here, but the original file is long gone.\n";
And when you run it:
% chmod +x rmtest
% rmtest
Check file 'rmtest' before unlink
rmtest
Unlinking the file 'rmtest'
Check file 'rmtest' after unlink
ls: rmtest: No such file or directory
File should be now be gone from disk (but still in memory)
Try ^Z and check it with 'ls rmtest' ... (come back with 'fg')
 
Suspended
% ls rmtest
ls: rmtest: No such file or directory
% fg
rmtest
I'm still here, but the original file is long gone.
%

Replies are listed 'Best First'.
Re^3: Deleting a file after it runs?
by Tanktalus (Canon) on Oct 07, 2005 at 03:40 UTC

    You're both right. Try a bit more in your sample.

    When you run this, even after the file is unlinked, the *DATA filehandle still works. That's because the file is still physically on the disk, even though it has been unlinked from the directory tree. Once the file is finally closed, the filesystem is allowed to reuse that diskspace. To prove this, I created a ram disk (thanks to a recent thread ;-}), and added a check using df to see the filesystem being used. In this case I ram it and got output like this:
    $ cp z.pl /ram; perl /ram/z.pl Check file before unlink /ram/z.pl Filesystem 1K-blocks Used Available Use% Mounted on none 100 4 96 4% /ram Unlinking the file /ram/z.pl Check file after unlink ls: /ram/z.pl: No such file or directory Filesystem 1K-blocks Used Available Use% Mounted on none 100 4 96 4% /ram File should be now be gone from disk (but still in memory) Try ^Z and check it with 'ls /ram/z.pl' ... (come back with 'fg') I'm still here, but the original file is long gone. $ df -k /ram Filesystem 1K-blocks Used Available Use% Mounted on none 100 0 100 0% /ram
    Note how the file may have disappeared from /ram, but the disk usage wasn't actually freed up until I was done with the script.

    I re-ran the script without the __END__ marker or the usage of *DATA, and found that the script is closed after compilation as the diskspace is freed immediately. Again, you're both right. :-)

      I still don't think that's right, at least for my system, running Linux.  It might be somehow different because you're using a ramdisk, but when I run this program:
      #!/usr/bin/perl -w + my $iam = $0; my $lscmd = "ls -lt $iam"; my $dfcmd = "df --block-size=1 ."; + printf "Before remove\n"; system($lscmd); system($dfcmd); sleep 1; unlink $0; printf " After remove\n"; system($lscmd); system($dfcmd); sleep 1; printf "Try ^Z to see for yourself (cmd: $dfcmd) ...\n"; sleep 5; printf "Now exiting the program\n";
      it clearly shows that the space is freed up *before* the program exits.  The free space goes from 44290686976 bytes to 44290691072 (a difference of 4096 bytes) and remains at that value until after the program completes.  
      [liverpole@golux ~/perl]% chmod +x rmtest2 [liverpole@golux ~/perl]% ls -lt rmtest2 -rwxrwxr-x 1 liverpole liverpole 352 Oct 7 12:25 rmtest2* [liverpole@golux ~/perl]% rmtest2 Before remove -rwxrwxr-x 1 liverpole liverpole 352 Oct 7 12:25 rmtest2 Filesystem 1-blocks Used Available Use% Mounted on /dev/hda2 77584592896 29352763392 44290686976 40% / After remove ls: rmtest2: No such file or directory Filesystem 1-blocks Used Available Use% Mounted on /dev/hda2 77584592896 29352759296 44290691072 40% / Try ^Z to see for yourself (cmd: df --block-size=1 .) ... Suspended [liverpole@golux ~/perl]% ls -lt rmtest2 ls: rmtest2: No such file or directory [liverpole@golux ~/perl]% df --block-size=1 . Filesystem 1-blocks Used Available Use% Mounted on /dev/hda2 77584592896 29352759296 44290691072 40% / [liverpole@golux ~/perl]% fg rmtest2 Now exiting the program [liverpole@golux ~/perl]% df --block-size=1 . Filesystem 1-blocks Used Available Use% Mounted on /dev/hda2 77584592896 29352759296 44290691072 40% /

        I bet that's because perl opens the file, reads it, closes it and then runs the code.

        $ cat > hw.pl #!/usr/bin/perl print "Hello, World!\n"; sleep 5; print "exiting...\n"; $ chmod 755 !$ chmod 755 hw.pl $ strace -o abc -tt -ff -s 500 !$ strace -o abc -tt -ff -s 500 hw.pl $ _ (stripped strace output) 21:33:16.679617 open("/home/hue/lang/perl/hw.pl", O_RDONLY|O_LARGEFILE +) = 3 21:33:16.681557 read(3, "#!/usr/bin/perl\nprint \"Hello, World!\\n\";\ +nsleep 5;\nprint \"exiting...\\n\";\n", 4096) = 72 21:33:16.681985 read(3, "", 4096) = 0 21:33:16.682080 close(3) = 0 21:33:16.682336 write(1, "Hello, World!\n", 14) = 14 21:33:16.683833 nanosleep({5, 0}, {5, 0}) = 0 21:33:21.663964 write(1, "exiting...\n", 11) = 11

        Doing an lsof -n|grep hw shows that no process (except hw.pl itself) has the file opened, so when one unlinks it, the operation performs immediatly.

        --
        David Serrano