Mercurial > pkg
comparison previous-work/more_control_helpers/bin/forall_direntries_from @ 1:d6bef198ae71
add work by Matthias S. Benkmann which is the inspiration for this project.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 08 Jan 2013 11:45:01 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:0b7a589f6e9a | 1:d6bef198ae71 |
---|---|
1 #!/bin/bash | |
2 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de> | |
3 # You may do everything with this code except misrepresent its origin. | |
4 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND! | |
5 | |
6 #The following list should contain the mount points of all filesystems | |
7 #that are to be scanned as a space-separated list within parentheses. | |
8 #/ will usually be in this list and if you have /usr | |
9 #on a separate partition, it will also be in this list. Other non-special | |
10 #filesystems where package users could own files should also be put in this | |
11 #list. | |
12 #Mount points whose filesystems are special, such as procfs or sysfs must | |
13 #not be in this list. While a simple find on those special filesystems should | |
14 #be harmless, operations such as "-exec grep something" are NOT SAFE and may | |
15 #have HARMFUL SIDE-EFFECTS, especially when performed as root. | |
16 fs_to_scan=(/) | |
17 | |
18 #Files with a path prefix found in the following list are ignored. | |
19 #This list will usually contain the parent directory of your package users' | |
20 #home directories, because normally you don't want to scan those. You can | |
21 #also add other directories that will never contain package user files, such | |
22 #as /home. This reduces scan time. | |
23 #NOTE: The LFS-6.0 book uses a ramfs mounted on /dev and with that setup | |
24 #/dev does not need to be in the prune list. But since there is no requirement | |
25 #that /dev have its on filesystem it's better to prune it explicitly. | |
26 prune_prefixes=(/home /usr/src /dev /tools) #NO TRAILING SLASHES!!!! | |
27 | |
28 if [ $# -lt 1 -o "$1" = "--help" ]; then | |
29 echo 1>&2 | |
30 echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name> [<find-commands>]' | |
31 echo 1>&2 | |
32 echo 1>&2 ' If <find-commands> contains no action other than -prune, -print will be' | |
33 echo 1>&2 ' executed for all matching files.' | |
34 echo 1>&2 ' Entries will be matched if group and/or user equals <user_or_group_name>' | |
35 echo 1>&2 ' (numeric UID/GID allowed).' | |
36 echo 1>&2 ' All matching entries will be acted on, including device special files, so' | |
37 echo 1>&2 ' you should be extra careful with the <find-commands> you provide!' | |
38 echo 1>&2 | |
39 exit 1 | |
40 fi | |
41 | |
42 #suppress ugly debug output from shell | |
43 trap ':' SIGPIPE | |
44 | |
45 ugname="$1" | |
46 shift 1 #remove user_or_group_name from argument list | |
47 | |
48 # Recent versions of find issue a warning if "-depth" is listed after a | |
49 # non-option argument. To prevent this warning if -depth is passed to | |
50 # this script, we pick up the "-depth" argument here to move it to the | |
51 # front later on. | |
52 depth="" | |
53 if [ "_$1" = "_-depth" ]; then | |
54 depth=-depth | |
55 shift 1 | |
56 fi | |
57 | |
58 ugmatcher=(-false) | |
59 #test if find accepts ugname as a user, and append to ugmatcher if it does | |
60 if find / -maxdepth 0 -user "$ugname" >/dev/null 2>&1 ; then | |
61 ugmatcher[${#ugmatcher[@]}]="-or" | |
62 ugmatcher[${#ugmatcher[@]}]="-user" | |
63 ugmatcher[${#ugmatcher[@]}]="$ugname" | |
64 fi | |
65 #test if find accepts ugname as a group, and append to ugmatcher if it does | |
66 if find / -maxdepth 0 -group "$ugname" >/dev/null 2>&1 ; then | |
67 ugmatcher[${#ugmatcher[@]}]="-or" | |
68 ugmatcher[${#ugmatcher[@]}]="-group" | |
69 ugmatcher[${#ugmatcher[@]}]="$ugname" | |
70 fi | |
71 | |
72 #if find accepted ugname as neither user nor group, then exit | |
73 if [ "${#ugmatcher[@]}" = 1 ]; then | |
74 echo 1>&2 'find does not accept `'"$ugname'"' as group or user name' | |
75 exit 1 | |
76 fi | |
77 | |
78 #construct find commands that match the prune_prefixes. Each prefix will be | |
79 #matched as -path <prefix> -or -path <prefix>/* | |
80 #so that the directory itself and all subdirectories are matched. | |
81 y=(\( -false) | |
82 for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) | |
83 do | |
84 y[${#y[@]}]='-or' | |
85 y[${#y[@]}]=-path | |
86 y[${#y[@]}]="${prune_prefixes[$i]}" | |
87 y[${#y[@]}]='-or' | |
88 y[${#y[@]}]=-path | |
89 y[${#y[@]}]="${prune_prefixes[$i]}/*" | |
90 done | |
91 y[${#y[@]}]=')' | |
92 | |
93 #In the following find command, the part | |
94 # -not ( ( "${y[@]}" -prune ) -or "${y[@]}" ) | |
95 #is responsible for preventing the files that match prune_prefixes from | |
96 #being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because | |
97 #-prune has no effect and is always false when -depth is used. | |
98 #The -true before "$@" ensures that -depth can be passed as only parameter. | |
99 find "${fs_to_scan[@]}" $depth -xdev -noleaf \ | |
100 -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \ | |
101 -and \( "${ugmatcher[@]}" \) -and \( -true "$@" \) |