perms.plugin.zsh 2.54 KB
Newer Older
Rory Hardy's avatar
Rory Hardy committed
1
2
3
4
5
6
7
8
# Some useful commands for setting permissions.
#
# Rory Hardy [GneatGeek]
# Andrew Janke [apjanke]

### Aliases

# Set all files' permissions to 644 recursively in a directory
9
10
11
set644() {
	find "${@:-.}" -type f ! -perm 644 -print0 | xargs -0 chmod 644
}
Rory Hardy's avatar
Rory Hardy committed
12
13

# Set all directories' permissions to 755 recursively in a directory
14
15
16
set755() {
	find "${@:-.}" -type d ! -perm 755 -print0 | xargs -0 chmod 755
}
Rory Hardy's avatar
Rory Hardy committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

### Functions

# fixperms - fix permissions on files and directories, with confirmation
# Returns 0 on success, nonzero if any errors occurred
fixperms () {
  local opts confirm target exit_status chmod_opts use_slow_mode
  zparseopts -E -D -a opts -help -slow v+=chmod_opts
  if [[ $# > 1 || -n "${opts[(r)--help]}" ]]; then
    cat <<EOF
Usage: fixperms [-v] [--help] [--slow] [target]

  target  is the file or directory to change permissions on. If omitted,
          the current directory is taken to be the target.

  -v      enables verbose output (may be supplied multiple times)

  --slow  will use a slower but more robust mode, which is effective if
          directories themselves have permissions that forbid you from
          traversing them.

EOF
    exit_status=$(( $# > 1 ))
    return $exit_status
  fi

  if [[ $# == 0 ]]; then
    target="."
  else
    target="$1"
  fi
  if [[ -n ${opts[(r)--slow]} ]]; then use_slow=true; else use_slow=false; fi

  # Because this requires confirmation, bail in noninteractive shells
  if [[ ! -o interactive ]]; then
    echo "fixperms: cannot run in noninteractive shell"
    return 1
  fi

  echo "Fixing perms on $target?"
  printf '%s' "Proceed? (y|n) "
  read confirm
  if [[ "$confirm" != y ]]; then
    # User aborted
    return 1
  fi

  # This xargs form is faster than -exec chmod <N> {} \; but will encounter
  # issues if the directories themselves have permissions such that you can't
  # recurse in to them. If that happens, just rerun this a few times.
  exit_status=0;
  if [[ $use_slow == true ]]; then
    # Process directories first so non-traversable ones are fixed as we go
70
    find "$target" -type d ! -perm 755 -exec chmod $chmod_opts 755 {} \;
Rory Hardy's avatar
Rory Hardy committed
71
    if [[ $? != 0 ]]; then exit_status=$?; fi
72
    find "$target" -type f ! -perm 644 -exec chmod $chmod_opts 644 {} \;
Rory Hardy's avatar
Rory Hardy committed
73
74
    if [[ $? != 0 ]]; then exit_status=$?; fi
  else
75
    find "$target" -type d ! -perm 755 -print0 | xargs -0 chmod $chmod_opts 755
Rory Hardy's avatar
Rory Hardy committed
76
    if [[ $? != 0 ]]; then exit_status=$?; fi
77
    find "$target" -type f ! -perm 644 -print0 | xargs -0 chmod $chmod_opts 644
Rory Hardy's avatar
Rory Hardy committed
78
79
80
81
82
    if [[ $? != 0 ]]; then exit_status=$?; fi
  fi
  echo "Complete"
  return $exit_status
}