Making LS aware of hidden folders

Michael Nowak
Mac O’Clock
Published in
6 min readMay 29, 2020

In no event shall the authors be liable for any claim, damages or other liability, arising from, out of or in connection with the article or the use or other dealings with the article. Please proceed at your own risk.

I like to keep my file system organized and free from distraction of folders that I do not use. The “Documents”, “Desktop”, “Pictures”, and other folders generated by the system in my home folder are some nuisances that come to mind.

In order to hide folders such as these in a Finder window, I update the tags on each folder to label them hidden. I accomplish this by opening a terminal window and executing:

cd ~/
sudo chflags hidden Documents Music Desktop Movies Pictures Public

The first command changes the directory to where these folders live (my home directory). The second command applies the hidden tag to the folders given to it as arguments and will request that I enter my account’s password — you need to be an administrator on your machine continue.

After executing these commands, my home directory is cleaner:

The folders that were once bothering me are now hidden from view. However, if I open a terminal window and execute the following commands:

cd ~/
ls -G

The “hidden” folders are clearly visible.

I would like to make ls aware of the hidden flag on folders, so that those flagged do not appear in directory listings.

Years ago, I came across a post (https://superuser.com/questions/290666/making-ls-aware-of-hidden-file-fla) from 2012 that helped me accomplish just that. In this article, we will bring that procedure up to date and document what has worked for me on MacOS Catalina.

To get started,

  1. Download and install Xcode from the App Store
  2. Go to the Apple Open Source (http://www.opensource.apple.com) website and download thefile_cmds, libutil, and xnu sources for your version of Mac OS X. Warning: I had trouble getting the Catalina (10.15.5) version of the files to compile. Consequently, I used the file_cmds, libutil, and xnu sources for Yosemite (10.10.5) — despite running Catalina, this approach worked satisfactorily.
  3. Extract the source archives to a known directory (you will need the paths later).
  4. In the file_cmds directory, open file_cmds.xcodeproj with Xcode.

The first thing that we are going to do in Xcode is to set the build target to ls. To accomplish this, click the icon in the screen capture below circled in black (the text maybe different from “unlink”).

A drop down will appear, from which you will select ls.

Next, click on the file_cmd project on the left (circled in black below)

and a new panel will be shown in the primary display:

In the left sub panel, under targets, select ls.

and then click on the “Build Settings” tab forls

Using the search field, look-up “Header Search Paths”

The results returned from your search should (somewhere) include a field for “Header Search Path”:

Double-click the right side of the field — within the rectangular region in the screenshot below:

and a new window will appear:

Using the “+” mark, add the paths to the libutil andxnu folders created when you extracted both of their archives (note: your paths will likely differ from mine).

Confirm that the paths to these folders has been added to the “Header Search Paths”:

Next, open Print.c in the ls directory

and comment out #include <membershipPriv.h>. In the original post (https://superuser.com/questions/290666/making-ls-aware-of-hidden-file-flag) on this method, the author claims that this change should break something, although they are not aware what. Years later, I have not experienced any issues that I can attribute to commenting this include directive out.

Now open upls.c. In the display function, you should find the following comment:

/* Only display dot file if -a/-A set. */

Subsequently, comment out the block of code described by that comment — your version may have a different implementation than mine.

In its place, add the following code from the original source (https://superuser.com/questions/290666/making-ls-aware-of-hidden-file-flag):

* Only display dot file and file with hidden flag if -a/-A set. */
sp = cur->fts_statp;
if (((sp != NULL && (sp->st_flags & 0x8000)) || cur->fts_name[0] == '.') && !f_listdot) {
cur->fts_number = NO_PRINT;
continue;
}

Build the project with Command(⌘)-B; the build should succeed.

Select the Products folder from the Project navigator, right-click on ls and select “Show in Finder”.

Create a new directory in your home folder called bin. Drag and drop the ls executable into this directory:

Finally, prepend the newly created bin folder to your path. You can do this for zsh and bash shells by executing

printf "\nPATH=$HOME/bin:$PATH" >> $HOME/.zshrc
printf "\nPATH=$HOME/bin:$PATH" >> $HOME/.bash_profile

Then restart your shell session (exit terminal, start again).

Now when you execute ls -G you should not see any folders with the hidden flag set.

To ultimately make “vanilla” ls aware of the hidden files, you will need to alias ls to ls -G (and you get color too!). You can modify your zsh and/or bash “configuration” files to do this as follows:

# for zsh, in .zshrc
alias ls="command ls -G"

# for bash, in .bash_profile or .profile
alias ls="ls -G"

The added statement to the configuration file must come after the statement that adds $home/bin to your PATH. After you have done this, restart your shell session (exit terminal, start again).

When you execute lsyou should not see any folders with the hidden flag set.

ls is aware of the hidden folders! To give credit where credit is due, I reiterate that this write-up is a modernization and elaboration of this nine-year old source (https://superuser.com/questions/290666/making-ls-aware-of-hidden-file-flag).

--

--