I'm having trouble quoting a filename that's eventually passed to chmod
. The script was originally written for SSH's StrictModes
and authorized_keys
, but I had to expand it due to a bad UMASK
that caused some filesystem discomfort. The script is below, and its producing boatloads of:
chmod: /Users/<user>/Library/Application: No such file or directory
chmod: Support/TextMate/Managed/Bundles/HTML.tmbundle/Macros/Delete: No such file or directory
chmod: whitespace: No such file or directory
chmod: between: No such file or directory
chmod: tags.plist: No such file or directory
...
chmod: /Users/<user>/Library/Caches/com.operasoftware.Opera/Media: No such file or directory
chmod: Cache/index: No such file or directory
cut: stdin: Illegal byte sequence
...
I've tried a few workarounds, but none of them have helped. I tried double quoting like ""$file""
, but the issue persisted. I also tried the back ticks (that are discouraged in this case), but the issue persisted.
The closest I got to actually quoting was the dysfunctional "\"""$file""\""
. But then chmod
complained the filename (with quotes) was not a real file:
$ sudo ~/fix-perms.sh
chmod: "/Users/Shared/.localized": No such file or directory
chmod: "/Users/<user>/.CFUserTextEncoding": No such file or directory
chmod: "/Users/<user>/.lesshst": No such file or directory
How do I quote the filename that comes out of find
that gets passed onto chmod
? Or how do I get chmod
to take the filename as a single argument?
$ cat ~/fix-perms.sh
#!/bin/bash
# Directories
find /Users/* -type d -exec chmod 0700 {} \;
find /Users/Shared -type d -exec chmod 0777 {} \;
# Files
for file in `find /Users/* -type f`;
do
if [ `file "$file" | cut -d":" -f 2 | grep -i -c executable` -eq 0 ];
then
`chmod 0600 "$file"`
else
`chmod 0700 "$file"`
fi
done
for user in `ls -A /Users`;
do
if [ -e "/Users/$user/.ssh/authorized_keys" ];
then
chmod 0600 "/Users/${user}/.ssh/authorized_keys"
fi
done
Best Answer
fwiw,
find [options] -print0
, when used in conjunction with (piped to)xargs -0 [options]
, handles filenames with spaces, without messing withfor
loops orIFS
: