0

I am trying to run a single command to change all .DS_Store files within a directory and all subdirectories recursively.

So far, I have been using the following commands to find the files, set their date modified to Jan 1 01:01:01 2001, and then to find them and set their permissions to read only for user, group, and everyone .

find . -name '.DS_Store' -print0 | xargs -0 sudo touch -t 200101010101
find . -name '.DS_Store' -print0 | xargs -0 sudo chmod 444

I'm guessing there is a more efficient way to do this with a single command, but I'm not sure how to use the output of the find command in more than a single following command.

Ideally, if there is any error/failure encountered with any of the files/commands, I would want to have the command line stop and output the error message rather than continuing to execute. I've seen elsewhere that using && to separate commands on a single line would do this, but am not sure how to use this in conjunction with the output from the find command.

This question is about a smaller part of a larger task I'm trying to accomplish. I've almost got it all working now except part of the script that only seems to work when I run it from terminal directly. Here's a link to the main issue in case anyone here might be able to help: Service to execute series of commands on selected folders to eliminate issues with .DS_Store files in Finder

MikMak
  • 2,169

2 Answers2

2

You can do that by using the -exec option and using its output as argument for a subshell:

find . -name '.DS_Store' -exec zsh -c 'touch -t 200101010101 "$1" && sudo chmod 444 "$1" || echo "$1" >> errors.txt' zsh {} \;

As you can see I use zsh {} to pass an argument to zsh -c, which allows me to use the output of find via $1. Note that you need to use double quotes here, e.g. to avoid filenames containing spaces causing problems.

I use && to only continue with the next command, if the previous exited without an error.

If an error occurs, || allows me to run a command on failure, for example writing the filename into a errors.txt file.

mashuptwice
  • 3,395
1

How about:

find . -name '.DS_Store' -exec sudo touch -t 200101010101 {} + -exec sudo chmod 444 {} + -print

(remember, -exec with + builds a single command with all files as arguments)

Paul
  • 1,804