0

There is a folder which is being created within another folder in my home directory, and I want to be able to analyse the contents of this folder, however, I have a problem: as the folder is created, it is then immediately deleted by the same program that creates it. Is there any way that I can allow it to create the folder, but then not to delete it? I am running Ubuntu GNOME 15.10 with GNOME 3.18.

muru
  • 193,181
  • 53
  • 473
  • 722
  • Just as a suggestion, you might also want to ask this on Unix & Linux – Daniel Nov 10 '15 at 20:14
  • @Daniel the "also" is a problem - cross-posting is generally unwelcome. – muru Nov 10 '15 at 20:15
  • Sorry, wasn't aware of that ^ – Daniel Nov 10 '15 at 20:16
  • How soon is "immediately"? – muru Nov 10 '15 at 20:18
  • @muru: Less than a second. Just basically a flash. –  Nov 10 '15 at 20:19
  • Isn't that what the [sticky bit](https://en.wikipedia.org/wiki/Sticky_bit) is for? – Jos Nov 10 '15 at 20:22
  • For humans. You could try using `inotify` (http://askubuntu.com/a/60310/158442) or `incron` (http://askubuntu.com/a/546264/158442) to immediately run `chmod -w` on the parent directory. – muru Nov 10 '15 at 20:23
  • @Jos Sticky bit prohibits deletion by all but the owner, if I remember right. Owner can still delete, if he has write permissions. – Byte Commander Nov 10 '15 at 20:25
  • But the program does not need to be the owner of the files it creates. – Jos Nov 10 '15 at 20:26
  • I am the owner of the file it creates and I own it (the program). –  Nov 10 '15 at 20:29
  • How often is the folder created / deleted? Seconds? Minutes? Hours? – kos Nov 10 '15 at 20:42
  • @kos: It is created when I execute something special, I don't know how long it exactly takes to be deleted, but it is literally a flash, less than a second. –  Nov 10 '15 at 20:45
  • @muru: How exactly do I use and configure those tools? –  Nov 10 '15 at 20:51
  • But do you have control on its creation? if so a simple loop might do to quickly dump some informations: `while [ ! -d ]; do sleep 0.1; done; stat >out` – kos Nov 10 '15 at 20:51
  • @kos: Well, I sort of do... It gets created every time I open a closed-source application that I have installed. –  Nov 10 '15 at 20:52
  • @ParanoidPanda see update. – muru Nov 10 '15 at 21:45

1 Answers1

2

There are no permission settings that can do this, even using ACLs, but you can have a race with the program, using inotifywait:

In one terminal, I ran:

while sleep 0.5; do if mkdir foo/bar; then echo foo; rmdir foo/bar; fi; done

As you can see, this creates a directory, echoes a message and removes the directory - all of which happens very quickly by human standards.

And in another:

while true
do
    if inotifywait -e create foo
    then
        chmod -w foo
        if [[ -d foo/bar ]]
        then
            break 
        else
            chmod +w foo
        fi
    fi
done

This command waits for creation of anything in foo, then removes write permissions from foo, and tests if it was in time for catching the sub directory. If not, it adds back the write permission, and starts again.

After waiting a bit:

foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
rmdir: failed to remove ‘foo/bar’: Permission denied
mkdir: cannot create directory ‘foo/bar’: File exists
mkdir: cannot create directory ‘foo/bar’: File exists
mkdir: cannot create directory ‘foo/bar’: File exists
mkdir: cannot create directory ‘foo/bar’: File exists

This is relying on a race condition, so whether you can catch it is a matter of luck.


foo/bar is the directory that the program makes. If you don't know the name of it, you can try other ways:

  • ensure that there's nothing else in the directory, so when a subdirectory is created, foo/ is non-empty. Some tests for non-empty directory are available in this U&L post:

    shopt -s nullglob
    if [ -n "$(ls -A foo/)" ]
    then
        break
    

    This worked fast enough.

  • read the name of the created directory from inotifywait's output:

    if dir=$(inotifywait -e create --format '%f' foo)
    then
        chmod -w foo
        if [[ -d foo/$dir ]]
    

    This didn't work (yet) for me; the overhead of creating subshell seems to make it just sufficiently slow enough for the other loop to win each time. Maybe coded in C using the inotify API, this could work.

muru
  • 193,181
  • 53
  • 473
  • 722