in reply to Deleting a file after it runs?

On unix, you can also say,

unlink $0;
You can say that at any point in the program, and unix will go ahead and remove the file from the directory without losing the object of the file handle. The removal is completed and disk space released once your program closes.

$ cat > try.pl #!/usr/bin/perl print $0, $/; unlink $0; print "Feeling faint . . .\n"; $ chmod 755 try.pl $ cp try.pl try.bak $ ls try.* try.bak try.pl $ ./try.pl ./try.pl Feeling faint . . . $ ls try.* try.bak $

After Compline,
Zaxo

Replies are listed 'Best First'.
Re^2: Deleting a file after it runs?
by liverpole (Monsignor) on Oct 06, 2005 at 21:57 UTC
        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.
    %
    

      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% /