Reputation: 73
I am trying to change the permissions on all files with group or owner 1001 to 1000.
I've tested these 2 commands on a small directory and they both work, but when I try using them all the way from root, I get the 'argument list too long' error
find /share/CACHEDEV2_DATA/Container -user 1001 -exec chown 1000 {} +
find /share/CACHEDEV2_DATA/Container -group 1001 -exec chgrp 1000 {} +
Is there a different way I can execute the command to get around this error?
Upvotes: 2
Views: 2592
Reputation: 14452
Short version:
Given number of files, placing all arguments on a single command will fail (too many arguments, or too long command line). Using xargs to batch lines will solve the line length problem, and improve the performance.
# Preferred - using NUL to separate files
find /share/CACHEDEV2_DATA/Container -user 1001 -print0 | xargs -0 -L50 chown 1000
# Without protection against "special" file names (risky)
find /share/CACHEDEV2_DATA/Container -user 1001 | xargs -L50 chown 1000
Long Answer:
As indicated by some commentors, the source of the problem is the trailing '+' (instead of the more commonly used trailing ';') to the find command. From info find
... The SVR4 edition of Unix introduced a slight variation, which involves terminating the command with '+' instead:
find /var/tmp/stuff -mtime +90 -exec /bin/rm {} \+
The above use of '-exec' causes 'find' to build up a long command line and then issue it. ...
So find offers two bulking options - one file per line, and ALL files per line.
Clearly, this is a case to integrate with 'xargs', which provide more flexible way to batch lines - by argument count (-L...) or line size (-s). Also, should consider using the null terminator to support situation where file names have spaces, magic characters ('*'), etc.
Upvotes: 1
Reputation: 207485
You can do that with GNU Parallel quite simply and efficiently if you use the -X
option which passes as many arguments as your system's ARGMAX
allows.
I am not at a machine to check this, so try it on a small directory with a copy of just a few files before you let rip through a whole filesystem:
find <STARTDIRECTORY> -user 1001 -print0 | parallel --dry-run -X -0 chown 1000 {}
If that looks correct, run it again but omitting the --dry-run
.
Upvotes: 1