Fix delzip
This commit is contained in:
+69
-2
@@ -21,10 +21,77 @@ alias ls='ls --color=always'
|
||||
alias cgrep='grep --color=always'
|
||||
alias cdiff='git diff --color-words --no-index'
|
||||
|
||||
# Remove the files an archive extracted into the current directory.
|
||||
# Lists what it will delete and asks first; -f skips the prompt, -n dry-runs.
|
||||
# Directories are only removed if they end up empty.
|
||||
delzip() {
|
||||
unzip -Z -1 "$@" | xargs -I{} rm -rf {}
|
||||
emulate -L zsh
|
||||
setopt local_options
|
||||
|
||||
local dry=0 force=0
|
||||
while [[ $1 == -[nf] ]]; do
|
||||
[[ $1 == -n ]] && dry=1 || force=1
|
||||
shift
|
||||
done
|
||||
(( $# )) || { print -ru2 "usage: delzip [-n|-f] <archive.zip>..."; return 2 }
|
||||
|
||||
local zip entry parent
|
||||
local -a entries files dirs
|
||||
for zip in "$@"; do
|
||||
[[ -f $zip ]] || { print -ru2 "delzip: no such file: $zip"; return 1 }
|
||||
entries=("${(f)$(unzip -Z -1 -- $zip)}") || return 1
|
||||
for entry in $entries; do
|
||||
[[ -n $entry ]] || continue
|
||||
# zip-slip guard: never touch anything outside the cwd
|
||||
if [[ $entry == (/|~)* || $entry == (|*/)..(|/*) ]]; then
|
||||
print -ru2 "delzip: refusing unsafe path: $entry"
|
||||
return 1
|
||||
fi
|
||||
[[ $entry == */ ]] && dirs+=(${entry%/}) || files+=($entry)
|
||||
# many archives omit directory entries, so infer them from the
|
||||
# paths as well; unzip creates those dirs regardless
|
||||
parent=${entry%/}
|
||||
while [[ $parent == */* ]]; do
|
||||
parent=${parent%/*}
|
||||
dirs+=($parent)
|
||||
done
|
||||
done
|
||||
done
|
||||
dirs=(${(u)dirs})
|
||||
|
||||
# only keep what is actually on disk, so the list reflects reality;
|
||||
# -L catches broken symlinks, which -e alone misses
|
||||
local -a present
|
||||
present=(); for entry in $files; do [[ -e $entry || -L $entry ]] && present+=($entry); done
|
||||
files=($present)
|
||||
present=(); for entry in $dirs; do [[ -d $entry ]] && present+=($entry); done
|
||||
dirs=($present)
|
||||
|
||||
(( $#files + $#dirs )) || { print -ru2 "delzip: nothing to remove here (already gone?)"; return 1 }
|
||||
|
||||
if (( dry )); then
|
||||
print -rl -- ${files} ${(O)dirs}
|
||||
return 0
|
||||
fi
|
||||
|
||||
if (( ! force )); then
|
||||
[[ -t 0 ]] || { print -ru2 "delzip: not a terminal, use -f to skip the prompt"; return 1 }
|
||||
print -r -- "delzip: remove ${#files} file(s) under ${PWD}:"
|
||||
print -rl -- " "${^files[1,20]}
|
||||
(( $#files > 20 )) && print -r -- " ... and $(( $#files - 20 )) more"
|
||||
(( $#dirs )) && print -r -- "plus ${#dirs} directory/ies, if they end up empty."
|
||||
read -q "?Proceed? [y/N] " || { print -r -- $'\naborted'; return 1 }
|
||||
print
|
||||
fi
|
||||
|
||||
(( $#files )) && rm -f -- $files
|
||||
# deepest first, so parents can empty out; rmdir refuses non-empty dirs
|
||||
for entry in ${(O)dirs}; do
|
||||
[[ -d $entry ]] && rmdir -- $entry 2>/dev/null
|
||||
done
|
||||
return 0
|
||||
}
|
||||
export MITMPROXY_SSLKEYLOGFILE='~/.mitmproxy/sslkeylogfile.txt'
|
||||
export MITMPROXY_SSLKEYLOGFILE="$HOME/.mitmproxy/sslkeylogfile.txt"
|
||||
|
||||
unset ZSH_AUTOSUGGEST_USE_ASYNC
|
||||
export LANG='en_US.UTF-8'
|
||||
|
||||
Reference in New Issue
Block a user