2

Please review these codes that are aimed to do basically the same task (finding the main .htaccess of the site and changing it):

for dir in "$HOME"/public_html/*.{com,co.il}/; do 
  if pushd "$dir"; then 
    chmod 644 .htaccess 
    popd 
  fi 
done 2>/dev/null 

and:

find "$HOME"/public_html/*.{com,co.il} -name ".htaccess" -exec chmod 644 {} \;

Should these also affect .htaccess files in subdirectories of each directory under public_html?

4

Indeed, the first loop only considers files in the immediate directory structure you've listed (with the wildcards filled in, of course). The find command that you've listed does not restrict itself to any level of directory structure, and would run chmod on any and all files named .htaccess in the directory tree.

To restrict the find command to only the directory structure it starts in (noting that you've given it, via globs, multiple starting directories), add the -maxdepth 1 predicate:

find "$HOME"/public_html/*.{com,co.il} -maxdepth 1 -name ".htaccess" -exec chmod 644 {} \;
4

Your first code snippet:

for dir in "$HOME"/public_html/*.{com,co.il}/; do 
  if pushd "$dir"; then 
    chmod 644 .htaccess 
    popd 
  fi 
done 2>/dev/null 

This could be rewritten without changing into and out of directories, as

for dir in "$HOME"/public_html/*.{com,co.il}/; do 
    chmod 644 "$dir/.htaccess" 
done 2>/dev/null 

and even be shortened (or at least modified) from that to

for pathname in "$HOME"/public_html/*.{com,co.il}/.htaccess; do 
    chmod 644 "$pathname" 
done 2>/dev/null 

which, if there are not too many of those files, could be done with

chmod 644 "$HOME"/public_html/*.{com,co.il}/.htaccess 2>/dev/null

This only looks at the .htaccess files in subdirectories of public_html, and not further down into the directory structure.

Note that the last two variations will not try to chmod missing files. The original loop and my first variant of it assumes that there are .htaccess files to chmod in the given directories, while the last two variants just loops over the .htaccess files that are actually present. The earlier loops gives you an opportunity to test whether a directory contains such a file (which you don't do), whereas the later commands assumes that the .htaccess files that are there are the only ones that we need to concern ourselves with.

Your second code snippet:

find "$HOME"/public_html/*.{com,co.il} -name ".htaccess" -exec chmod 644 {} \;

This on the other hand looks for .htaccess files anywhere in or below the directories defined by "$HOME"/public_html/*.{com,co.il}. You could remedy that by adding -maxdepth 1 before -name. This would stop find from recursing down into subdirectories of the given directories and force it to stop at the top level.

Adding -maxdepth 1 to find makes it work pretty much the same way as my last actual loop above.

Neither of the two commands tries to verify that the found .htaccess files are actually regular files and not directories etc. In your loop, you could do that with a -f test, and in the find command, you could do that by saying -type f before the -exec.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.