Automatically delete empty QubesIncoming subdirectories

Hi,

This is a simple guide, but I’m quite happy with this setup so I’m sharing it here :slight_smile:

I was bored to have many QubesIncoming subdirectories in my qubes, after receiving a file I usually move it from there, but I always forget to clean the empty directory.

This command line to add in /rw/config/rc.local will automatically remove all empty sub directories, but not remove /home/user/QubesIncoming itself because it’s it’s bookmarked in the file browser, it would disappear when deleted.

test ! -d /home/user/QubesIncoming || find '/home/user/QubesIncoming/' -mindepth 1 -type d -exec rmdir '{}' \;
7 Likes

You run this with

... >/dev/null 2>&1

… right? Otherwise you’ll get some output…

EDIT: nevermind, it finally dawned on me that it’s rc.local, not cron.

I share this feel.

I prefer to keep some logs, just in case :smiley:

1 Like

Nice! Some of my VMs always seem to be littered with a hundred empty ~/QubesIncoming/disp1234 directories. (Hope it was okay to add -maxdepth 1 etc. Edit: Sorry, my bad for being too quick to assume that no -maxdepth 1 was unintentional. I’ve removed it again.)

I also thought about adding “-maxdepth 1” (and changing the order in which the arguments appear, because -mindepth and -maxdepth are global options and should appear before -type …) but I realised it does not really matter. Why, you ask? Because if there are any sub-directories under ~QubesIncoming/dispNNNN/ which are not empty, the rmdir will fail, and if they are empty… no harm done. In any case, the results are the same and the chance of finding sub-directories is minimal…

I often have subdirectories, and I want them to disappear if empty :slight_smile:

1 Like

Then you really don’t need “-maxdepth”! :smile:

That’s why I’m not using it :smiley:

Maybe you’d also want -depth for the find command, to remove empty directories recursively?

(I’ve reverted my edit from -exec rmdir {} \; to -exec rmdir {} + too, just in case it somehow breaks anything for this use case. :star: Earned ‘Most Bungled Edit’)

1 Like

I only use -mindepth to not have QubesIncoming itself to be deleted, I don’t understand why I would need other flags :thinking:

For example, without -depth (using rmdir -v for illustration):

$ mkdir -p /home/user/QubesIncoming/vm/a/b/c
$ find /home/user/QubesIncoming -mindepth 1 -type d -exec rmdir -v {} \;
rmdir: removing directory, '/home/user/QubesIncoming/vm'
rmdir: failed to remove '/home/user/QubesIncoming/vm': Directory not empty
rmdir: removing directory, '/home/user/QubesIncoming/vm/a'
rmdir: failed to remove '/home/user/QubesIncoming/vm/a': Directory not empty
rmdir: removing directory, '/home/user/QubesIncoming/vm/a/b'
rmdir: failed to remove '/home/user/QubesIncoming/vm/a/b': Directory not empty
rmdir: removing directory, '/home/user/QubesIncoming/vm/a/b/c'
find: ‘/home/user/QubesIncoming/vm/a/b/c’: No such file or directory

The same again with -depth:

$ mkdir -p /home/user/QubesIncoming/vm/a/b/c
$ find /home/user/QubesIncoming -depth -mindepth 1 -type d -exec rmdir -v {} \;
rmdir: removing directory, '/home/user/QubesIncoming/vm/a/b/c'
rmdir: removing directory, '/home/user/QubesIncoming/vm/a/b'
rmdir: removing directory, '/home/user/QubesIncoming/vm/a'
rmdir: removing directory, '/home/user/QubesIncoming/vm'
2 Likes

Ah, that’s a good one :slight_smile:

Nice solution, thank you. There is an enhancement issue on github with similar request, so, maybe it will be working out of box some day.

I would recommend to follow shellcheck recommendations and add single quotes around path just to explicitly show it is a string (I know that the path has no spaces). And ‘{}’ should be single-quoted, too.

ShellCheck v0.9.0 doesn’t recommend either of these though. Seems fine to me as is?

I’ve done reasonably well with rmdir * done in QubesIncoming. I don’t typically have subdirectories below the VM name level.

Only infrequently is this an actual issue for me though since almost everything of mine is a named disposable anyway. The stuff disappears on shutdown.

I do not like it, not fine.

  • If path has spaces it should be quoted (with single quotes, not double), if not it still should quoted for consistency and proper string highlighting (including forum).

  • About ‘{}’: it looks obvious to me, because it is not a part of the bash syntax but a string that is given as a string argument to find, so, there is no reason not to make it a proper string for clarity and consistency. Also you can open man find and in the EXAMPLES section it is used single-quoted, too.

Eh, it’s a matter of taste. Some people like overquoting (for consistency, or out of an abundance of caution against obscure shell features), some dislike it (because it increases line noise, or makes it look like something interesting is going on that has to be protected against).

But the code is correct with or without it. foo isn’t any less of a string than "foo" in (ba)sh code, and {} is exempt from brace expansion. If even ShellCheck doesn’t care… ¯\_(ツ)_/¯

No, it’s more of code style and best practices that I advise to use consistently, especially for shell/bash, which is an awful language, if a language at all.

DRY also recommends doing this to avoid constant string duplication:

qubes_incoming_path='/home/user/QubesIncoming'
test ! -d "${qubes_incoming_path}" || find "${qubes_incoming_path}" -mindepth 1 -type d -exec rmdir '{}' \;

About ‘{}’, check out man find:

Executing a command for each file

Run file on every file in or below the current directory.

$ find . -type f -exec file '{}' \;

Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though single quotes could have been used in that case also.