-
Notifications
You must be signed in to change notification settings - Fork 1
/
findlike
executable file
·130 lines (119 loc) · 2.66 KB
/
findlike
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/sh
# POSIX Shell function to implement mininal find-like command
# Difference with find behavior :
# * does not follow dot-named item (like: find ! -name '.*' ) EDIT: it now follow hidden files
# Useful for :
# * call a shell function (find use subprocess, can not call defined function)
# * detecting deadlink and more ...
# ! not exists (or permission denied)
# f file
# d directory
# s socket
# p pipe (FIFO)
# b block special file
# c character special file
# U unknown
# lX symlink of type X
# l! dead [sym]link
# lf symlink to file
# ld symlink to directory
# pfind() <callback> [<directory> [<directories ...>]]
pfind() {
local hand="$1";shift
local level=${level:-0} # usefull in case of MINDEPTH=0
if [ $# -eq 0 ]; then
# level=$(( ${level:-0} + 1))
pfind "$hand" .
# level=$(( ${level:-0} - 1))
return $?
fi
if [ $# -gt 1 ] ;then
# level=$(( ${level:-0} + 1))
for item in "$@"; do
pfind "$hand" "$item"
done
# level=$(( ${level:-0} - 1))
return $?
fi
local item="$1"
local type1=''
if [ -h "$item" ]; then
type1='l'
elif [ ! -e "$item" ]; then continue ;# empty directory => item='dir/*'
elif [ -d "$item" ]; then
if "$hand" 'd' "$item" && \
[ -r "$item/" ]; then
level=$(( ${level:-0} + 1))
for childitem in "$item"/*; do
case "$childitem" in
*/.|*/..) continue ;;
esac
pfind "$hand" "$childitem"
done
for childitem in "$item"/.*; do
case "$childitem" in
*/.|*/..) continue ;;
esac
pfind "$hand" "$childitem"
done
level=$(( ${level:-0} - 1))
fi
#level=$(( ${level:-0} - 1))
return 0
fi
local type='U'
if [ ! -e "$item" ]; then type='!';
elif [ -f "$item" ]; then type='f';
elif [ -d "$item" ]; then type='d';
elif [ -S "$item" ]; then type='s';
elif [ -p "$item" ]; then type='p';
elif [ -b "$item" ]; then type='b';
elif [ -c "$item" ]; then type='c';
fi
"$hand" "$type1$type" "$item"
# level=$(( ${level:-0} - 1))
return $?
}
mindepth() {
if [ ${level:-0} -ge ${MINDEPTH:-0} ]; then
return 1
fi
return 0
}
maxdepth() {
if [ -n "${MAXDEPTH:-}" ] && [ ${level:-0} -gt ${MAXDEPTH} ]; then
return 1
fi
return 0
}
showall() {
maxdepth || return 1
mindepth || echo "$1 $2 (${level:-0})"
if [ "$1" = "d" ] && [ ! -r "$2" ]; then return 1; fi
return 0
}
showdeadlink() {
maxdepth || return 1
if [ "$1" = "l!" ]; then
mindepth || echo "$2"
fi
}
showfile() {
maxdepth || return 1
case "$1" in
f|lf)
mindepth 1 || echo "${level:-0} $2" ;;
esac
}
showdir() {
maxdepth || return 1
case "$1" in
d|ld)
mindepth 1 || echo "${level} $2" ;;
esac
}
if [ $# -eq 0 ]; then
echo "Usage: $0 <showfile|showdir|showall|showdeadlink> [directories...]"
exit 1
fi
pfind "$@"