1

I'm trying to perform a complex operation on a selected directory and all subdirectories (recursively) in Finder using a Service I can assign to a keyboard shortcut.

First off, when simply issuing most of the commands via terminal, I have found that I can achieve the desired outcome. The problem comes in when trying to invoke a second function/script to handle a subroutine.

Here's what I have so far, starting with the shell script (/bin/bash) used by the Automator service (which receives input as arguments from selected files or folders in Finder.app):

for dir; do
    echo "$dir"
    "$HOME"/fixDsStoreFiles "$dir"
done

This calls the fixDsStoreFiles script that resides within my home folder to go to work on the selected folder. Here's the first part of it.

#!/bin/bash
# first, clear script log file on desktop
echo '' >|~/Desktop/testScript.txt
# Check that exactly one parameter has been specified - the directory
if [ $# -eq 1 ]; then
   # Go to that directory or give up and die
   cd "$1" || exit 1
   #  use touch to create a .DS_Store file in the current directory, and/or set date modified of the existing file to Jan 1, 2001 01:01AM
   touch -t 200101010101 .DS_Store
   # copy .DS_Store file to all subdirectories recursively
   find . -type d -mindepth 1 -exec cp -n ".DS_Store" {} \;

And here's where it breaks down. If I execute the following command via terminal with the selected directory in Finder as the current dir, the subscript works as intended.

find . -type d -mindepth 1 -exec $HOME/testScript {} \;

But when trying to execute it from the fixDsStoreFiles script, or when adding the testScript code as a function within the fixDsStoreFiles script (up at the top), it fails to perform the necessary step.

Here's the code for the testScript.

# find & trash all empty folders (the ones containing nothing but a .DS_Store file)
#!/bin/bash
cd "$1"
dir=.
absDir=$(cd -- "$dir" && pwd)
eval=$(find . \! -name ".DS_Store");
OUT=();
for I in $eval
do
OUT=${OUT:+$OUT}$I
done
if [ $OUT == . ]; then
echo "\"$absDir\" - EMPTY DIRECTORY TRASHED!" >>~/Desktop/testScriptLog.txt && trash -F "$absDir"
else echo "\"$absDir\" is NOT empty" >>~/Desktop/testScriptLog.txt
fi

Basically, I'm concatenating & parsing the output of the find command to see if a given subdirectory contains anything but the .DS_Store file. If it is otherwise empty, the output will simply be .. If it contains other files/folders, the concatenated string will list all of the files/folders in the folder in one string.

Here's the remainder of the fixDsStoreFiles script that would run after the testScript completes its function to remove the [nearly] empty folders.

   # find all .DS_Store files, set date modified to Jan 1, 2001 01:01AM, and make them read only
   find . -name '.DS_Store' -exec zsh -c 'touch -t 200101010101 "$1" && chmod 444 "$1" || echo "$1" >> ~/Desktop/fixDsStoreFiles_errors.txt' zsh {} \;
   # run syncFF in current directory
   open -a "SyncFF" "$1"
fi

For anyone who doesn't have it, SyncFF is a nice utility with a GUI that scans a directory structure recursively setting the date modified for each folder to the most recently-updated file within it.

Unfortunately, however, if the folder is empty aside from a .DS_Store file, it retains the current day/time since there are no files that SyncFF will scan and use to set the folder date.

This is why I am removing those folders using the testScript: so that, ultimately, the entire directory structure will only have any of its folders updated by the date of the actual project files/folders within them that were actually modified - NOT just by the pesky .DS_Store file getting updated when viewing the folder, thus screwing up revision control, sorting of working directories by modification date, etc.

This has been a long time in the works, and is the best/most-functional/lowest-maintenance idea I've come up with to solve this problem so far. By ensuring every folder has a .DS_Store file, that the mod date for all of them is much earlier than any of the other files, and that they are all set to read only, this should prevent any future updating of folder modification dates due to browsing or changing the view settings of the hierarchy, and only working file modifications in any of the project folders will actually update their date modified.

Granted, this means sacrificing some of the functionality that the .DS_Store files help macOS/Finder to facilitate. But it's a small price to pay for being able to keep things organized by the date you last worked on them.

Hopefully this will be enough [but not too much] info that someone can help me to figure out what I'm doing wrong here so that I can get this whole thing working with a single keystroke as desired.

I sincerely appreciate any time & effort anyone can devote to helping me with this!

MikMak
  • 2,169

0 Answers0