0

I know how to view hidden files in the Finder. Instead, what I'd like to do is list files in the shell/Terminal by the same criteria that the Finder uses for files that are hidden. (My objective is to collect metrics using a cronjob/launchd script that are consistent with what appears in the UI.)

This is proving to be more difficult than it sounds. Here is an example case of the ways I am aware of to hide a file from the Finder (Big Sur 11.6, Apple Silicon, APFS):

mkdir test
cd test
touch regular hidden invisible .dotfile
SetFile -a V invisible
chflags nohidden invisible
chflags hidden hidden

This requres that SetFile be present, which is available with Developer Tools.

The expected outcome of the command or script is one file, regular. All three of the other files are not visible in Finder under usual circumstances. I would like the solution to only require native tools (no Developer Tools or gnu coreutils/homebrew and the like).

So far, my approach would be to loop through all files output by ls -lO | awk 'NR!=1 && $5!~/hidden/ { print $0 }' (this filters out dotfiles and the hidden file flag), and use GetFileInfo (another Developer Tool installed alongside SetFile) to filter out the invisible attribute. However, this requires that Developer Tools be installed, which I would prefer to avoid the dependency on, and also seems awkward and excessively complicated--and likely also inefficient if there are thousands of files in a directory.

I suspect that the other options would be to manually parse the output of xattr -px com.apple.FinderInfo invisible (more complicated but avoids the GetFileInfo dependency) or to use osascript to somehow make use of the Finder's existing logic instead of attempting to reimplement it using BSD tools.

Edit: Since apparently some users' setfile commands set the hidden flag, I added chflags nohidden invisible to the test case since it is entirely likely for the filesystem to contain files (created via other means) which only have the extended attribute FinderInfo flag and do not have the BSD file flag.

13
  • 2
    RE: "(My objective is to collect metrics using a cronjob/launchd script that are consistent with what appears in the UI.)" -- I'm curious as to what practical purpose this will serve? Sep 19 at 15:42
  • @user3439894 d.pr/i/la1Xza Metrics are collected to be actionable, and inconsistent data is not actionable.
    – NReilingh
    Sep 19 at 16:23
  • The Finder has an option ignore the visibility settings, so using something like osascript to have the it return the names of files it can see may not work the way you want.
    – red_menace
    Sep 19 at 16:47
  • 1
    Maybe tell application id "com.apple.systemevents" to return every item in the folder "/path/to/folder" where it is visible (or …whose visible = true) ?
    – CJK
    Sep 21 at 2:25
  • 1
    @CJK Excuse my slang, lol. "Cash money", i.e. very excellent, an absolute win, exactly what I was looking for. I'd accept that as an answer if you'd care to write it up!
    – NReilingh
    Sep 24 at 12:04
1

Originally posted as a comment on the off-chance this might produce the required result, although wasn’t able to test myself at the time. However, the OP confirmed that, on his system (Big Sur 11.6, Apple Sillicon, APFS), the following command returns the contents of a directory that matches what is visible in a Finder window that is opened and pointed at the directory path:

tell application id ("com.apple.systemevents") ¬
        to get every item in the folder named ¬
        "/path/to/folder" where it is visible

This returns a list of file and folder references that resolve much faster than Finder file references. It will be even more performant if one retrieves a list of file paths instead:

tell application id ("com.apple.systemevents") ¬
        to get the POSIX path of every item in ¬
        folder "/path/to/folder" whose visible ¬
        is true

Since System Events accepts simple file paths in place of file references as parameters in many of its commands (e.g. move, delete, etc.), this can speed things up dramatically, and in most cases, will be infinity time quicker than Finder without blocking it.

Should you require an alias list in order to make use of commands only available through Finder, e.g. reveal, then:

tell application id ("com.apple.systemevents") ¬
        to get every alias in the folder named ¬
        "/path/to/folder" where it is visible

tell application id ("com.apple.Finder") ¬
        to get the result as alias list

tbc

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .