Tell me more ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

When I plug-in an USB stick (FAT) into my Mac or Ubuntu machine, all files have the executable bits set. After having copied the directory structure to my hard disk how do I remove the executable bits recursively just from the files and keep those on the directories?

share|improve this question

3 Answers

up vote 10 down vote accepted

A single command variant (starting in the current directory):

chmod -R -x+X *

Explanation:

  • -R - operate recursively
  • -x - remove executable flags for all users
  • +X - set executable flags for all users if it is a directory

In this case the capital X applies only to directories because all executable flags were cleared by -x. Otherwise +X sets executable flag(s) also if the flag was originally set for any of user, group or others.

Note: I tested the command with GNU chmod (on Ubuntu). I am not sure about the BSD chmod which is present on Mac OS X.

share|improve this answer
1  
seems not to work on OS X 10.7.5 - chmod -R -v -v -x+X * does not print anything. – Mike L. Nov 20 '12 at 14:41
2  
Just figured out on OS X you have to do it separately in two commands: sudo chmod -R -x * && sudo chmod -R +X * – drvdijk Feb 21 at 3:08

If you cd into the correct path first:

find . -type f -exec chmod -x {} \;

The find finds all files of type 'f' (which means regular file) in the path . and then calls chmod -x on each file. The {} gets substituted for the file name and the \; terminates the chmod command.

share|improve this answer
1  
If your find supports it, use -exec ... \+ instead of -exec ... \; — it'll require fewer fork+execs. If it doesn't, use find ... -print0 | xargs -0 .... – ephemient Jun 8 '12 at 19:49

The chmod -x+X way did not work for me on ubuntu either, thus I wrote this minimal python script:

#!/usr/bin/python3
import os
for par, dirs, files in os.walk('.'):
    for d in dirs:
        os.chmod(par + '/' + d, 0o755)
    for f in files:
        os.chmod(par + '/' + f, 0o644)

If there might be any fancy extra stuff such as sockets in your filesystem, you may want to surround the last chmod with a try/catch.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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