summaryrefslogtreecommitdiff
path: root/bin/hstow
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2023-01-18 13:24:47 -0700
committerSean Whitton <spwhitton@spwhitton.name>2023-01-18 13:24:51 -0700
commitc50e6e4519d7c4bfd8fe1e642bf6c565a0106222 (patch)
tree962b41ee42e8af0bfef1140a0db8a9ca5d634478 /bin/hstow
parent67849a1c42de52b225cae5b50f93aa5ec1cb4b79 (diff)
downloaddotfiles-c50e6e4519d7c4bfd8fe1e642bf6c565a0106222.tar.gz
hstow: speed up unstowing by using more streaming
Diffstat (limited to 'bin/hstow')
-rwxr-xr-xbin/hstow34
1 files changed, 21 insertions, 13 deletions
diff --git a/bin/hstow b/bin/hstow
index 311fce2a..c10b4907 100755
--- a/bin/hstow
+++ b/bin/hstow
@@ -50,6 +50,15 @@ if ! command -v readlink >/dev/null; then
}
fi
+# Here we unconditionally bypass readlink(1), for speed.
+# The long regexp is because only BREs have backreferences in POSIX.
+readlinks () {
+ while read -r line; do
+ printf '%s\t%s\n' "$line" "$(ls -ld "$line")"
+ done | sed \
+'s/\([^\t]*\)\t\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{8\}\1 -> /\1\t/'
+}
+
disjoin_hstow_file () {
if [ -e "$DIR/$1" ]; then
while read -r line; do
@@ -148,19 +157,18 @@ unstow () {
for file in \
$(find . ! \( -user "$(id -un)" -o -group "$(id -gn)" \) \
-prune -o -type l ! -name . ! -name "$cchars" -print \
- | grep -Ev "$dirs_pat"); do
- if readlink "$file" | grep -Eq '^(\.\./)*\.STOW/'"$NAME/"; then
- rm "$file"
- while true; do
- file="$(dirname $file)"
- [ "$file" = . ] && break
- if [ -z "$(dir_contents $file)" ]; then
- rmdir "$file"
- else
- break
- fi
- done
- fi
+ | grep -Ev "$dirs_pat" | readlinks | awk -F'\t' \
+ '$2 ~ /^(\.\.\/)*\.STOW\/'"$NAME"'\// { print $1 }'); do
+ rm "$file"
+ while true; do
+ file="$(dirname $file)"
+ [ "$file" = . ] && break
+ if [ -z "$(dir_contents $file)" ]; then
+ rmdir "$file"
+ else
+ break
+ fi
+ done
done
[ -e "$HOME/.STOW/$NAME" ] && rm "$HOME/.STOW/$NAME"
if [ -d "$HOME/.STOW" ] \