Bash - Recursively change ownership of only the directories which belong to a certain user/group - linux

I have a directory (we will call /files) with ~1300 subdirectories, each of which contains further subdirectories and files.
90% of the top level directories in /files belong to apache:apache and the rest belong to root:root. I need everything to belong to apache:apache.
I think if I do a recursive chown on the whole lot it will be quite extreme, so I was wondering if there's a more efficient way to recursively change ownership of just the root:root directories to apache:apache.
Bonus if chmod can be done on these directories in the same way.

Your recursive chown would have probably been done already, but you could use this instead:
find . -type d \( ! -user apache -o ! -group apache \) -print0 | xargs -0 chown apache:apache
To change directories that have the wrong permission:
find . -type d ! -perm 755 -print0 | xargs -0 chmod 755

Using linux's find command is going to help there:
find /files -user root -group root -type d \
-exec chmod something {} \; -exec chown apache.apache {} \;
for more details on WHY that works there is http://www.explainshell.com/explain?cmd=find+%2Ffiles+-user+root+-group+root+-type+d+-exec+foo+\%3B

Related

how to find all directories in /home that are not owned by root and change their permissions to ensure they have 711 permission?

I try to find all directories in /home that are not owned by root and change their permissions to ensure they have 711 permission in the same command.
find \home type -d -not -user root -ls | chmod 711 {} \
But the command I used doesn't work.
The following should work:
find /home -type d -not -user root -exec chmod 711 {} +
The -exec action allows you to run a separate executable (in this case chmod) and supply the found names to it. The + at the end allows find to run chmod with multiple names at once.
The above includes fixes for a few typos: \home should be /home, type -d should be -type d.
The first instruction has wrong syntax. You could try:
find /home -type d -not -user root -ls
Also, you shouldn't use "ls" if you care about performance. Instead I suggest using the -exec switch.
Good luck

How to search (using find command) for directories and copy all the files and directory itself to another directory in linux?

How to search (using find command) for directories and copy all the files and directory itself to another directory in linux?
Here is what I have so far:
find -type d -name "*.ABC" -exec {} /Desktop/NewFile \;
I get this as output:
find: './GAE/.ABC: PERMISSION DENIED
Please Help, Thanks!
Your error here above has nothing to do with file read permission. You're trying to execute the directories you find! Avoid running commands as root or sudo unless: (1) you really need it and (2) you really know what you're doing. Quite often people asking for root or sudo privileges are exactly the ones should not have it.
That said... there are several ways to copy a directory tree under *nix. This is just one possible approach:
$ find <start> -type d -name \*.ABC -exec cp -av {} <target> \;
Where:
<start> is a directory name. It's used to tell find where to start its search (for example /usr/local or $HOME)
<target> is another directory name to define the final destination of your copied directories
UPDATE
In case you want to search for multiple paths...
$ find <start> -type d \( -name \*.ABC -o -name \*.DEF \) -exec cp -av {} <target> \;
This should work:
find ./source_dir -name \*.png -print0 | xargs -0 cp -t path/to/destination
For more info, you can look up here.

changing permissions of files in a directory recursively

I am trying to change the permissions of a files present in a directory and subdirectories using the below command and running into below error..can anyone help?
user#machine:/local/mnt/workspace$ find . -type f -exec chmod 644 {} \;
chmod: changing permissions of `./halimpl/ncihal/adaptation/NonVolatileStore.cpp': Operation not permitted
you can run the following command:
#chown -R directory_path
But it will change the permissions of directories also.
For only files, you can run.
#find directory_path -type f -exec chmod 644 {} \;
It also looks like you dont have enough permissions. try
#sudo find directory_path -type f -exec chmod 644 {} \;
or run the command as root user.
It looks to me like you don't have permission to change NonVolatileStore.cpp.
Are you aware of chmod's -R switch that recursively changes permissions?
if you have the root privilege, try:
sudo find . -type f -exec chmod 644 {} \;
It could be that you simply don't own that file. Run an ls -l on it to see full permissions and who the owner is.
It could also be the filesystem is read only.

List too long to chmod recursively

I have tried the following command to chmod many images within a folder...
chown -R apache:apache *
But i get the follwing error
-bash: /usr/bin: Argument list too long
I then tried ...
ls | xargs chown -R apache:apache *
and then get the following message...
-bash: /usr/bin/xargs: Argument list too long
Does anyone have any way to do this? I'm stumped :(
Many thanks
William
Omit the * after xargs chown because it will try to add the list of all file names twice twice (once from ls and then again from *).
Try
chown -R apache:apache .
This changes the current folder (.) and everything in it and always works. If you need different permissions for the folder itself, write them down and restore them afterwards using chown without -R.
If you really want to process only the contents of the folder, this will work:
find . -maxdepth 1 -not -name "." -print0 | xargs --null chown -R apache:apache
This may work:
find . -maxdepth 1 -not -name -exec chown -R apache:apache {} \;
You can simply pass the current directory to chown -R:
chown -R apache:apache .
The one corner case where this is incorrect is if you want all files and subdirectories, but not the current directory and the .dotfiles in it, to have the new owner. The rest of this answer explains approaches for that scenario in more detail, but if you don't need that, you can stop reading here.
If you have root or equivalent privileges, doing a cleanup back to the original owner without -R is probably acceptable; or you can fix the xargs to avoid the pesky, buggy ls and take out the incorrect final * argument from the OP's attempt:
printf '%s\0' * | xargs -r0 chmod -R apache:apache
Notice the GNU extension to use a null byte as separator. If you don't have -0 in your xargs, maybe revert to find, as suggested already in an older answer.
find . -maxdepth 1 -name '*' -exec chmod -R apache:apache {} +
If your find doesn't understand -exec ... {} + try -exec ... {} \; instead.

recursively removing permissions under root folder

i am new to linux platform and now i wanted to remove write permissions of all the php files under my root folder. It would be appreciable if somebody can suggest a solution.
thanks and regards
tismon
find / -name '*.php' -exec chmod a-w {} \;
An alternate option would be to use these 2 commands
cd /
chmod -R a-w *.php
But I also recommend (like Matthieu did) to have a look first, what files you are really modifying.
This will work:
find /root -type f -name "*php" | xargs chmod 664

Resources