Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I pressed ENTER after typing the following stupid command on my home directory:

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

What do you advise as a fix for this. My guess is that I can't do anything but do something like:

find . -type f -exec chmod og+x '{}' ';'

Or may be do some tricky stuff based on extensions (which doesn't seem very pertinent under Linux).

Or may be some of you has an idea or a pointer on how to know which file should be executable under linux and how to detect them to turn them back to executables...

share|improve this question
    
You may want to rephrase your question so it's clearer what you're wanting. I'm thinking you're interested in finding executables and putting them back the way they were before your find command but I'm not sure. If that's the case, you're probably in for a very manual process. The only thing you can really programmatically determine is whether something is an ELF binary, but that doesn't mean you necessarily want it to be executable (a shared object, for instance). –  Joel Davis Mar 18 at 22:28
    
At least you didn't chmod -x the directories! –  Keith Thompson Mar 18 at 22:29
1  
@Keith that would be much easier to fix. There's no ambiguity, and if find can't descend into them, just loop until it reaches the deepest levels. –  orion Mar 18 at 22:31
    
Is this actually causing you any problems? –  terdon Mar 18 at 22:31
    
Well, I pressed Ctrl-C quite fastn but I already found some .so files that are not executable anymore. So I suppose this will be an issue for me quite soon... –  Gauthier Boaglio Mar 18 at 22:36

3 Answers 3

up vote 6 down vote accepted

Here is a script that I wrote a while back to fix permissions on files copied from a FAT system. Won't work if the file names contain newlines (although if someone wants to fix it so that it does, feel free):

#!/bin/sh

[ $# != 0 ] && dir="$1" || dir=.

[ -d "$dir" ] || { echo "usage: $0 [dir]"; exit 1; }

cat <<- EOF
  Will recursively alter permissions under directory '$dir'.
  Consider backing up permissions with 'getfacl -R $dir' first.
  Continue? [Y/n]"
EOF

read reply
[ "$reply" = Y ] || exit 0

echo "Changing all directories to mode 755..."
find "$dir" -type d -exec chmod 755 {} +

# simplest way for now is just to make all files non executable, then fix ones which should be
echo "Changing all files to mode 644..."
find "$dir" -type f -exec chmod 644 {} +

# use a temp file instead of a variable since the shell will strip nulls from the string
tmpfile=$(mktemp)

# screwed if filename contains a newline - fixable with a better sed script
echo "Using magic to find executables..."
find $dir -type f -exec file -hN0 -e apptype -e cdf -e compress -e elf -e tar -e tokens {} + |
  sed -n '/\x0.*executable/p' >"$tmpfile"

# ELF binaries
echo "\nSetting ELF executables to mode 755...\n"
sed '/\x0.*ELF/!d; s/\x0.*$//' "$tmpfile" | xargs -rd '\n' chmod -c 755

scripts=$(sed '/\x0.*text/!d; s/\x0.*$//' "$tmpfile")

IFS="
"

# only make scripts executable if they have a shebang
echo "\nSetting scripts with a shebang to mode 755...\n"
for file in $scripts
do
  head "$file" | grep -q '^#!' && chmod -c 755 "$file"
done

rm "$tmpfile"
share|improve this answer
    
That sound very good. Thanks for that. –  Gauthier Boaglio Mar 18 at 23:06
    
@Gauthier, I do have to say that my shell scripting has came on a bit since I originally wrote this, so there are a couple of dodgy bits there. I will need to take some time to revisit it, but it should work ok for most cases on Linux, certainly for all sane executable names. –  Graeme Mar 18 at 23:12
1  
@Gauthier, a few minor changes, but its late for me so anything more substantial will have to wait. –  Graeme Mar 18 at 23:26
    
OK, thanks for that. But don't be in a hurry, since, as mentioned in a comment above, I reduced my scope to 109 files. Which can be safely managed by hand. Anyway, since this script would be very useful, for many purposes (not only related to my current issue), that would be great from you if you can provide a renewed one. Have a good rest ;) –  Gauthier Boaglio Mar 18 at 23:27
    
Your script worked like a charm on the main issued directory I had. Thank you so very much. –  Gauthier Boaglio Mar 19 at 0:19

One option is to leave it as it is and discover missing executable permissions when you need the files.

However, you can be smarter than that. First of all, if you use .sh extensions on shell scripts, you can chmod them with find. Similar for perl and python scripts. Additionally, you could loop through the files and look for the #! in the first line, if it exists, make the file executable.

And last, compiled binaries can be detected with file. For instance:

file clock_test
clock_test: ELF 64-bit LSB executable, x86-64, version 1 .......

Which you can test with | grep ELF. So you could just write a script that tests all these options and fix the permissions if it guesses it should be executable.

share|improve this answer
    
OK, tahnks. Personally, I always use .sh on my custom scripts, but the big issue is that I'm working on a cluster, for which I do not have root access (which is not that bad, for someone who run dangerous recursive commands ;). So, all my tools are installed in my home and should be damaged after that. –  Gauthier Boaglio Mar 18 at 22:40
1  
Checking with file should fix all binaries, no damage done. –  orion Mar 18 at 22:44
    
OK, good point. And regarding scripts, mine can be found with '.sh', even if I forget, some time to time, to make them start with a shebang. And most of the scripts provided with the tools I installed should have shebangs. So, I think that most of the pain can be solved like suggested by you and Graeme's script. With a slight modification to handle my .sh scripts with missing shebangs. –  Gauthier Boaglio Mar 18 at 22:53
    
@GauthierBoaglio if they don't have shebangs, then they can only be executed by calling sh on them directly, in which case it doesn't matter if they're executable or not. Or am I missing something? –  kundor Mar 19 at 1:18
    
Well, not exactly because I run bash scripts from bash shells: stackoverflow.com/a/9945113/1715716 –  Gauthier Boaglio Mar 19 at 2:30

Here is how we used to fix this in the old days (c. 1984)!

Now, in your case it was from your home directory, which makes it less likely this particular solution will help you, but, as others may run across this request AND will have done so from /, /usr, or another high-level directory, it is worth considering.

  1. Go to another server running the same OS. If you don't have one, instantiate it up on Amazon Web Services (AWS). It will likely qualify as a free instance considering how very little work it will take to get a reference listing of the affected directory tree.

  2. on a clean copy of the OS, ls -lR > /tmp/clean from the folder in which you started your recursive file munging

  3. do the same from your munged folder on the computer requiring the fix

  4. you will likely want to use cut to remove the dates and sizes, as they may differ do to minor/major version differences.

  5. diff the two files saving the output

  6. use the output to find the files where the permissions don't match.

Another approach would be to read the output from the clean OS's listing and use it to apply to correct permissions on your affected OS.

I hope this comes in handy to someone out there.

share|improve this answer
    
That's an interesting general information / approach, that gives me the idea to backup my files permissions and more generally, all the possible information concerning my files, to be able to restore some of them after some mistaken operation. So this can be very helpful, in my case as well. Thanks a lot Hugo! –  Gauthier Boaglio Mar 19 at 7:29
    
If I have time, and I really should find some, to write such a backup/recovery script, I'll share it. Or, more probably, googling a bit should avoid to reinvent the wheel. Cheers. –  Gauthier Boaglio Mar 19 at 7:38

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.