1. 47

What are the top level directories, what naming rules do you follow, and in general how do you keep $HOME clean?

    1. 19
      jtm@x1c ~ % ls
      TODO acme aux bin doc down git go mail mnt music rom www xen 
      • acme - additional scripts for acme.
      • aux - synonymous with “junk”.
      • doc - images, documents, slides, etc.
      • down - downloads
      • mail - emails in Maildir format.
      • www - source code for a static site.
      • xen - vm configurations.

      I’ve been meaning to add a cron job to delete anything in down that’s older than three days.. that folder tends to blow up.

      To keep junk from accumulating in $HOME, I use a shell function called “t” that will automatically cd to a temporary scratch space, so I don’t have to think about cleaning up junk that I don’t intend to keep. I use this almost every day.

      function t {
        cd $(mktemp -d /tmp/$1.XXXX)
      1. 15

        Instead of a t function, I have a ~/tmp folder.

        Because ~/tmp is persistent, I end up with stuff in there that I’m afraid to delete, so I made a ~/tmp/tmp for stuff that’s actually temporary.

        Because ~/tmp/tmp is persistent, I occasionally end up with stuff in there that I'm afraid to delete. I once just needed a temp folder quickly, but didn't feel like stuff in ~/tmp was safe to delete yet, so I made a ~/tmp/tmp/tmp`.

        I should add that t function to my rc.

      2. 3

        Ooo, I love the t function. I make temp dirs for stuff all the time. So simple, but really helpful - thanks for sharing!

      3. 2

        I have a similar j function which creates a named (default: junk) subdirectory in the current directory and cds to it. There is a corresponding jjj function which is essentially rm -fr junk. Because the new directory is under the current directory, I find it is easier to reference the original directory with .. rather than using "$OLDPWD".

    2. 12

      It seems like I’m the only here whose $HOME looks like a junkyard.

      1. 5

        Mine is a junkyard too. It (the /home partition) is also (relatively) small at 15gigs.

        Instead I keep a separate partition (/mnt/awal/) all clean and organized, and then symlink/source a few files and directories back into home. I find that this conveniently allows me to separate machine-agnostic things from machine-specific.

      2. 3

        No, you’re not alone. The only folder I create besides the usual XDG user directories is ~/code, for /bin there is already ~/.local/bin. In my humble opinion, micro managing dotfiles and $HOME subdirectories is plain procrastination (which is not a bad thing per se).

        Edit: typo.

    3. 10
      how do you keep $HOME clean

      $HOME is read-only:

      • New applications are not allowed to create directories or files in $HOME.
      • Existing non-compliant applications are gradually replaced by compliant ones.
      naming rules do you follow

      All dirs lowercase for better auto-completion.

      top level directories
      • .cache: XDG cache dir

      • .config: XDG config dir

      • .local: XDG “local” dir

      • apps: unmanaged third-party application binaries

      • audios: subfolders music and casts

      • backup: obvious

      • code: sources for my coding projects

      • desktop: files that are displayed on the dektop

      • documents: obvious

      • downloads: obvious

      • fonts: symlink to .local/share/fonts/

      • images: pictures, screenshots, wallpapers (I wanted to find a different name, because of the possible confusion with CD images, but the time made this concern obsolete)

      • public: shared directory, network-accessible

      • remote: remote mounts

      • videos: obvious

      1. 5

        New applications are not allowed to create directories or files in $HOME.

        easily the best idea that I have read regarding unix administration in a long time

      2. 5

        New applications are not allowed to create directories or files in $HOME.

        Do you have a technical way to enforce this, or do you just pay attention to the files and directories an app creates?

        1. 3

          Yes, chmod -222 $HOME does the enforcement for me.

          I wrote a more detailed step-by-step guide here.

      3. 2

        New applications are not allowed to create directories or files in $HOME.

        WOW. Why didn’t I think of that?! Thanks!

      4. 2

        I don’t understand. Home is read only, but you write a bunch of stuff there…what am I missing? Can you give me more details please?

        1. 3

          $HOME itself is read-only (chmod -222 $HOME), but existing files and folders are still writable.

          That’s how the amount of garbage .dotfiles is slowly decreasing on my machine: New ones can’t be added (because of the dir being read-only); and I’m removing existing ones as I migrate to better written applications.

          I wrote a more detailed step-by-step guide here.

          1. 1

            Ahhhh! Thank you!

    4. 8



    5. 4
      $ ls -F
      adm/ bak/ local/ mdc/ pro/ src/ x
      • adm: shitty administrative tasks, taxes, official letters, etc
      • bak: static read-only content, pdf and djvu books, music, test images
      • local: like /usr/local but for my user, ~/local/bin is in my PATH
      • mdc: teaching-related stuff, with one sub-folder for each course and each phd student
      • pro: non-teaching related professional projects
      • src: source codes compiled locally, including my repos
      • x: text-file with a to-do list
      1. 5

        Nice. I think this one is closest to what I currently do which is:

        :: ls
        base  desk  file  plug  self  work
        • base: the same as your local and in addition has config subdirectory for config files.
        • desk: serves as 3-in-1: desktop + downloads + temp files.
        • file: the same as your bak.
        • plug: mount points, dropbox, googledrive, sshfs. and everything of this nature.
        • self: things I do for and by myself.
        • work: work on request of others, seems to be your pro.

        Your adm would be within fille/documents and your mdc would be within self/teaching.

        BTW: I also noticed all your directories start with a different letter. Not sure if this is intentional, but a nice benefit of quickly being able to auto-complete. I do not like the default of “Downloads”, “Documents” for this reason.

      2. 3

        Man, thanks for src. I just called it Projects but never found it fitting.

    6. 3
      $ ls|wc -l

      Don’t even know if it would be worth it to try to organize.

    7. 3

      Downloads bin img lib sites src tmp torrents who www

      1. 1

        Very similar to mine, except I use tmp as downloads. What’s in the who folder?

        1. 5

          it’s my white/yellow pages. nested directories starting with last names or handles. i run a variant of research unix http://man.cat-v.org/unix_8th/7/tel to search an index generated by a cron job.

          1. 2

            Can you share this (and perhaps others) script?

            1. 2

              each final directory under who/ contains files like addr, email, tn, etc. cron runs http://plan9.stanleylieber.com/rc/nutel >$home/lib/tel to update the index. search using https://code.9front.org/hg/plan9front/file/754916eeedf1/rc/bin/tel

    8. 3

      I have an archive/0next folder where I put any files which are not actively being edited (or stored in my personal monorepo in ~/sys).

      Every 6-12 months I will rename 0next to archive-yyyy-mm-dd, and also save tarballs to AWS glacier and a Blu-ray disc.

      The benefits of this system are that I have a clear distinction between mutable files and immutable files. At any one time I only have a few GBs of working files. The rest is checksummed and trivially easy to recover (rm + s3 cp)

      Otherwise it’s a standard layout: documents, downloads, etc.

    9. 2
      • dev – for development projects,
      • dev/<programming language name> – for my C++ projects/inventions/snippets in this language,
      • dev/<programming language name>/tests – for snippets related to a programming language that test one concept, helps to learn the language and reference this particular feature in the future,
      • temp – a directory for various temporary stuff that I know can be removed, everything here is either truly temporary or can be easily regenerated,
      • temp/build – development artifacts built from sources inside dev directory. Normally I use cmake (for c/c++) everywhere so that it always supports out-of-tree build. This way I can just remove all binaries instantly without figuring out how to clean some particular source tree,
      • lab – my playground, testing some tools, resources for scripts,
      • env – sourced shell scripts on machines that require some more environment settings. I use it on MSYS2 to integrate Visual Studio installation into bash command line,
      • .dotfiles – my dotfiles, configs are symlinked to this directory,
      • tasks - at work, I use it for Jira tickets,
      • req/<name> - if someone wants something from me that requires preparation of some files, often I setup a directory here with person’s name, and I put files in its own dir,
      • bin - added to $PATH for my user, some executables are symlinked from ~/temp/build/ to here, or directly from ~/dev/ if they’re scripts,
      • apps – locally installed apps (IntelliJ IDEA, Eclipse, Ghidra, etc),
    10. 2

      bin, downloads, drawings, game-ideas, games, gaming, models, music, my.src, presentations, school, src, sync, tmp, work. Can’t remember when I actually came up with this structure but it’s basically embedded in my brain by now.

    11. 2
      $ ls
      code  data  snap  tmp
      • code - holds every projet I download/work on locally. I have one subdirectory for work
      • data - subdivided for any kind of data (images, videos, certs, nodes, templates, …) also hold mountpoints
      • data/$MOUNT - named after what’s mounted (onedrive, sharepoint, etc…)
      • snap - Auto-created by the snap command. If you know how to get rid of that, I’d be thankful !
      • tmp - Non-persistent data. Either temp scripts or web downloads. I’ll mount it as tmpfs someday.

      There are also multiple hidden directory that I use on a daily basis:

      • ~/.local/bin - personnal scripts.
      • ~/.cache/mail - emails in Maildir format (sync’d over IMAP).
      • ~/.pw - passwords in encrypted format (see safe).
    12. 2

      There are a few directories present on all of my machines:

      • bin - scripts, tmp binaries
      • mnt - user mounts
      • workspace - everything related to code
        • $lang/$project - projects grouped by language
        • misc/$project - projects using multiple languages, configs, documentation
      • xdg user dirs (empty except for Downloads)
    13. 1

      Mine’s a mess, but I know where everything is, so I rarely bother cleaning it up.

      I have:

      ~/data/  - I added this recently when I was downloading shapefiles to play with GIS.  Basically just a collection of different data sets/
      ~/images/  - I like playing with computer graphics, and the output goes here
      ~/pdfs/ - Books and papers in PDF form
      ~/src/ - My source code
      ~/oss_src/ - Open source projects I build from source but don't plan on contributing code to (SBCL, Emacs, etc.)
    14. 1
      • ~/bin
      • ~/bin/foo.app (the target directory of some locally compiled project, like emacs)
      • ~/bin/foo -> foo.app/bin/foo (see, I don’t want to pollute my path, so I put a symlink in ~/bin that points at the binary.)
      • ~/bin/bar (shell script)
      • ~/scratch (This is a directory I create on all my machines. It’s not exactly tmp. I use it like a junk drawer and workspace. It’s currently 7.6gb on my work machine and there are like three specific files in there that I know of. The rest could be deleted. The oldest files in there are from 2012.)
      • ~/src or ~/projects (First I had src and it was a mixture of my projects, third party projects that I’d modified, and third party projects that I have no intention of modifying. Later, I got the idea of separating the wheat from the chaff. But, I’m pretty sure I now have some non-modified third party projects in my ~/projects now, because ~/src wasn’t mounted the other day or something, or I’m just really messy??)
      • ~/Downloads -> ~/downloads (Now that /u/soc shared this “read-only $HOME” idea with me, I won’t have to create this symlink anymore.)
      • ~/media or /media (These only exist on the older machines and they have subdirs like music and video)
      • ~/old-home, ~/namagiri-home, ~/debzero-home (Of all my junk in $HOME, these are probably what I’m most ashamed of. They are just full copies of various previous $HOMEs on previous incarnations of the same machine or other machines. hold on let me hit ctrl-r real quick to show you something: ssh -i ~/old-home/hobbes/.ssh/id_rsa *****.*** See? Ashamed. So many reasons.)
      1. 2
        • ~/scratch/left and ~/scratch/right These are persistent text files that always have the same name but with wildly varying contents. I keep them there for a great purpose.. I keep them open in an editor and I keep them open in a visual diff tool (meld or winmerge). So, I copy/paste some contents into them and refresh the diff tool. Bam. Any application that has a clipboard now has a visual diff feature. Kinda. I use this sooo often!
    15. 1

      I don’t organize my $home. I’m a chaotic type of person. the oldest directory bears a september 1997 timestamp.

      I use lots of finding “functions” which utilize locate or fd and lr

      for example

      lr -G -om $(fd --maxdepth 1 -t d '[a-zA-Z0-9]{1,10}-[0-9]{1,5}-sql$' ${HOME})

      lists all project directories named like (customer abbreviation)-(ticket number)-sql

      Some of these funktions are piped to fzf -because the list became too long- so I can find anything even quicker than the orderly and tidy guys click through the deep project directory hierarchy with the mouse in file browser.

      A similar function finds sublimetext project files, and the subsequent fzf opens the project in sublimetext.

      So my approach is to have a consistent naming and use custom tools to find things.

    16. 1
      cadey:cadey@kahless ~ ./rw
      $ ls
      backup/  bin/  code/  dl/  go/  irc/  life/  music/  org/  pictures/  prefix/  public_html/  sdk/  snap/  texmf/  tmp/
      • backup: backups
      • bin: random tools that aren’t properly installed in other ways
      • code: where I write code in
      • dl: downloads
      • go: my $GOPATH
      • irc: IRC logs, many gigabytes of them
      • life: where I keep some private keys and information
      • music: music that mpd cycles through
      • org: from a failed org-mode experiment of mine
      • pictures: mostly archives from image boorus
      • prefix: my $PREFIX for software that’s installed less improperly
      • public_html: https://xena.greedo.xeserv.us
      • sdk: where my go compilers live (artifact of https://godoc.org/golang.org/dl)
      • texmf: I think TeXLive did this
      • tmp: temporary files
    17. 1

      I keep all code inside ~/src sorted by theme. And search file system with Alfred to open projects in VS Code or cd quickly to folder in iTerm.

    18. 1

      On Windows, aka where my more important private documents live (laptops are ephemeral): hardly at all.

      On Linux, I’ve long stuck mostly with the Ubuntu/Debian defaults (which means Freedesktop I guess):

      • So ~/Documents
      • and ~/Pictures
      • and ~/Downloads
      • Also I use ~/code for my code, subdivided by work/github/misc/dotfiles (from git)
      • and a ~/tmp
      • and a ~/bin

      I have a few files in .config/ but it’s just one start and end-hook for zsh to overwrite params.

      I really don’t have a strong opinion on any of this. Except that I’m lazy and thus need a short bin and tmp dir :P

    19. 1
      $ ls -F
      Archive.zip  Maildir/     bin@         repos/       sandbox/
      • Archive.zip created every few days that zips Maildir
      • Maildir mail contents
      • bin symlinks to repos/bin_files/ -> https://github.com/zg/bin_files
      • repos/ contains repositories I’ve cloned (including https://github.com/zg/dot_files, which I’ve symlinked contents up to ~, e.g. ~/.zshrc points at ~/repos/dot_files/.zshrc)
      • sandbox/ experimenting, so it’s a bag of dirt
    20. 1

      This is every folder I keep on all of my unix-like installations. I’ve found that this layout is pretty all- encompassing and is easy to look through.

      repos - git repos and folders of code that I didn’t write docs - any documents, books, code that isn’t in a repo, etc downloads - self explanatory media - all of my photos, music, and videos files - backups of files games - halo 2 and 3 running via wine, and ROM archives .scripts - everything that I want to be executable that I don’t want in my $PATH .minecraft - the most essential folder of the entire computer

    21. 1
      • prog/ - in-dev programming projects, basically whatever I write from scratch or fork for tweaking
      • dnload/ - downloads, further organised in coarse-grained subdirs, like nim-etc/, or editors-etc/, … - I try to never download anything without putting it in a subdir (old or new)
      • $MY_NAME/ - personal stuff, mostly in subdirs named by date, e.g. “2019-12 taxes/” etc.
      • photos/ - photos & videos, in dated subdirs, e.g. “2019-12-01..03 Some Place, trip with Some Friend/”
      • drafts/ - attempt at a log/notes, not working well yet
      • work/ - subdir present only at work, with subdirs for various tasks, and a separate mess in every one of them
      • bin/ - scripts
      • go/ - autogenerated by Go
      • tmp/ - stuff
      • a few temp. files lying around

      I think that’s mostly all, though I’m doing it from memory. Also I am trying to use home-manager, works for me for some stuff (esp. vimrc) but not for everything.

    22. 1

      Meme content/saves: I wget them directly into the home dir and move them into a archive storage at the beginning of each month.

      Git/sourcecode: Lives in ~/src, usually

      Config/Scripts: in ~/.config, which is tracked in git. There are various symlinks into ~/.config.

      Accounts on shared hosts also have a public readable public_html, even if there is no http server running usually.

      Like jtm, i use mktemp directories as scratchpad.

    23. 1
      • devel Projects I have personally written.
      • dl Assorted downloads.
      • games Source code and other files for (non-packaged, non-steam) games I play.
      • lang Miscellaneous conlang files.
      • media.txt List of media I would like to or have read/watched/listened to.
      • music Various musical projects.
      • opt The contents of /opt bind-mounted since I ran out of space on /.
      • pictures Pictures.
      • pnp Pen-and-paper rpg files.
      • school Files I created for school.
      • serial.txt Documentation for my usb-serial converter so I don’t forget what wire are which.
      • software Source code for any software I want to build/work on.
      • Steam Steam games not installed on my SSD.
      • taxes Copies of my tax returns and other forms.
      • videos Videos I have recorded.
      • work Copies of work-related forms.
    24. 1

      code documents downloads local sync private work

      • sync is a symlink to my dropbox folder under .local
      • private is the encfs mountpoint for a encrypted disk image in dropbox
      • local is bin/var/cache etc

      fixed the casing on documents & downloads with xdg vars, which most of the time works.

    25. 1

      bin, code, games, docs, dotfiles, downloads, vids, pics and leet. The last dir leet is something I’ve been keeping around in my home dir since my early Linux days – it essentially has code that isn’t mine, or other “leet” stuff. Haven’t bothered renaming it to something more mature. :’)

      The games dir is hardly ever populated, but it’s for when I have non-Steam games that I decide to play.

      1. 1

        I put my “leet” code into ~/code/clones/. Everything else that’s mine just goes into ~/code. I’m sure this opens up some useful cases where you want your parent directory to override things happening in clones/ but I haven’t needed to yet :)

    26. 1

      $ ls # i'm actually at work and just guesstimating what's on my computer from what's on my server

      band_project_names bin c-programming documents downloads erlang elixir forth game nim python retro src TODO websites

      basically organised by what they are. src/ is like /opt or /usr/local/src but shorter to type. websites is ripped websites.

    27. 1

      ls -l -d */

      Downloads/ Mail/ Pictures/ bin/ docs/ sync/ work/

    28. 1

      I… don’t. Mind you, I have been trying, but I’d probably need to have at it for a week straight to remove/organize all the cruft that has been accumulating over the last few years.

      I have sketched a tentative folder layout, though, which is in use on my netbook (and partially on my laptop):

      • doc/: assorted personal documents (PDF scans/JPEG photos + org-mode notes)
        • academy/
        • archive/
        • finance/
        • journal/
        • medical/
      • dev/: my own repositories, what I am actively developing
      • dat/: miscellaneous data files, minus books
      • etc/: assorted scripts & dotfiles, installed in their proper place via stow
      • lib/: books & assorted reading material, organized according to the Universal Decimal Classification - e.g.,
        • 0.Science_and_Knowledge/
          • 02.Librarianship/
            • 025.450.Decimal_classifications/
        • 1.Philosophy_Psychology/
        • 2.Religion_Theology/
        • 3.Social_sciences/
        • A.Fiction/
          • Pratchett_Terry/
      • tmp/: temporary files, including browser downloads and repos that I’m just checking out

      I name most files according to the following pattern, while taking care to not include “weird characters” (or even just spaces) in my filenames:


      It can be a bit of an hassle, but it makes locate actually useful.

      1. 1

        I know this is a really old thread, but thank you for the UDC idea! My $HOME/bib/text/ is the messiest part of my computer; I’ve been using a tentative author-name-title format, but it never struck me to use an actual indexing system. I’m going to implement this over the coming days.

    29. 1
      • repos - for WIP code
      • old-repos - for code I consider not under active development
      • church - a farm for ideas. I’ll write lots of experimental code here that I then borrow in more cohesive/focused projects
      • life - orgmode life planner files, symlinked from dotfiles
      • books - epub files, pdfs, etc. I’ve accumulated
      • bin - custom scripts/executables to put in PATH
      • school
      • dotfiles
    30. 1

      My $HOME directory contains some config files, a Desktop folder (where I keep everything of value) and a Downloads folder, which is sort of an inbox of things to review.

      I mainly work in the Desktop, which contains:

      • personal: which contains all my dotfiles (symlinked to where they should be), my files (invoices, ID and passport scans, digital backup of important paper documents…), my projects (basically a clone of all my repos and stuff in the works), my sites (SSH keys, Ansible playbooks, Terraform files, Kubernetes manifests, Docker stack files… As well as the source of my static sites) and my scripts (local cron jobs, mini utilities I use all the time, etc.). Also my encrypted password database file.
      • studies: I’m on my third year in university for CS, one folder per subject and a Python script where I track all my grades.
      • work: I do AWS as a side gig, so one folder per client, and one subfolder per project. Oh, and my CV in English and Spanish.

      I keep everything in Desktop so that I can restic it all at once into my over-engineered backup system.

      I’ve been happily using this system for half a decade, and I’m very happy with it.

      I don’t think your system for file org is much important, but rather sticking to it and using it daily. I’m writing this off my memory, because I know where everything is and that’s what makes it productive.

    31. 1

      I’ve got (copied from my emacs.d):

      ~/code/: programming and sysadmin related files

      ~/code/{c,haskell,go,...}: directories devoted to specific programming languages

      ~/code/etc/...: various other projects

      ~/dl/: downloads gathering directory, preferably empty

      ~/doc/: texts, presentations and notes

      ~/doc/org/: most org-mode related files

      ~/media/: general directory for digial media

      ~/media/{img,vid,music,...}: specific media directories

      ~/etc/: various other directories

      ~/etc/bin/: user binaries

      ~/etc/{mail,news,pub}: gnus related directories

      and a function like this in by bashrc:

      goto() {
      	case $1 in 
      	read) 		cd ~/doc/read			;;
      	vm)   		cd ~/code/etc/vm		;;
      	c)      	cd ~/code/c				;;
      	img)		cd ~/media/img			;;
      	compsci)	cd ~/doc/read/compsci	;;
      	go)			cd ~/code/go/src/		;;
      	lisp)		cd ~/code/lisp/			;;
      	web|www)	cd ~/code/web/www/		;;
      	dl)			cd ~/dl/				;;
      	pers)		cd ~/doc/pers/			;;
      	uni)		cd ~/doc/uni/			;;
    32. 1

      The main part of my $HOME is a hierarchy:


      which contains almost all of my configuration. Various dotfiles like .bashrc and .vimrc are symlinked into $HOME from std/bin. I replicate this hierarchy across 1000+ servers to give me my standard environment on those servers. I have a separate $HOME/bin for local additions applicable to only a single server environment. Almost all of my non-dotfile $HOME is symlinks.

    33. 1


      binaries and scripts I want to include in my $PATH


      I organize everything by repositories, like

      • development/sr.ht/jussi/repo-name
      • development/github.com/metosin/reitit


      A lot of various documents from my download directory, sorted by filetype, client name or content. I automate sorting these using Hazel.


      Automated by hazel as well. After a file has been in documents for 4 months, it’ll be archived (or deleted, depends on various things like content and client).