diff --git a/profile.d/filefct.sh b/profile.d/filefct.sh index 7358e84..7f666d5 100644 --- a/profile.d/filefct.sh +++ b/profile.d/filefct.sh @@ -99,6 +99,7 @@ expandlist() continue fi + local content for content in "${expanded[@]}"; do if (( matched )); then result+="$separator" @@ -106,6 +107,7 @@ expandlist() result+="\"$content\"" matched=1 done + unset content done shopt -u nullglob @@ -182,6 +184,7 @@ clean() (( ! recursive )) && findopt=(-maxdepth 1) (( ! force )) && rmopt=(-i) + local dir f for dir in "${dirlist[@]}"; do find "$dir" "${findopt[@]}" -type f \( -name "*~" -o -name "#*#" -o -name "*.bak" -o -name ".~*#" \) -print0 | while IFS= read -r -d '' f; do @@ -191,10 +194,18 @@ clean() else printf 'rm -- "%s"\n' "$f" fi + elif (( force )); then + # No confirmation: rm reads no stdin, so leave it attached + # to the find pipe (a /dev/tty redirect would fail when there + # is no controlling terminal, e.g. cron). + rm -- "$f" || disp E "Failed to remove \"$f\"." else - rm "${rmopt[@]}" -- "$f" + # Interactive rm -i: read the answer from the terminal, not + # from the find pipe that feeds this loop's stdin. + rm -i -- "$f" /dev/null || return 1 - if (( substchar_set )); then - rmspc ${recurs:+-r} -c "$substchar" ${verb:+-v} ${shell:+-s} - else - rmspc ${recurs:+-r} ${verb:+-v} ${shell:+-s} - fi + # Build the recursive argument list by value: the ${var:+-flag} + # idiom would expand on the *string* "0" (non-empty) and wrongly + # force -v/-s on every recursive call. + local rargs=(-r) + (( verb )) && rargs+=(-v) + (( shell )) && rargs+=(-s) + (( substchar_set )) && rargs+=(-c "$substchar") + rmspc "${rargs[@]}" popd >/dev/null || return 1 (( verb )) && disp I "Leaving directory $(pwd)/$lastdir" @@ -337,6 +352,7 @@ rmspc() fi fi done + unset f shopt -u nullglob } export -f rmspc @@ -462,15 +478,19 @@ file_stats() fi # Extension list filter + local exts if [[ -n "$ext_list" ]]; then IFS=',' read -ra exts <<< "$ext_list" find_cmd+=('(') + local i for i in "${!exts[@]}"; do [[ $i -ne 0 ]] && find_cmd+=(-o) find_cmd+=(-iname "*.${exts[$i]}") done + unset i find_cmd+=(')') fi + unset exts # Minimum/maximum size filters (evaluated in bytes) if [[ -n "$min_size" || -n "$max_size" ]]; then @@ -653,22 +673,26 @@ findbig() (( one_fs )) && _fd_args+=(--one-file-system) _fd_args+=(. "$dir") if (( details )); then + local line "$_fd" "${_fd_args[@]}" --exec stat --printf="%s %n\n" 2>/dev/null \ | sort -rn | head -n "$limit" \ | while IFS= read -r line; do local path="${line#* }" ls -ld -- "$path" done + unset line else "$_fd" "${_fd_args[@]}" --exec stat --printf="%s %n\n" 2>/dev/null \ | sort -rn | head -n "$limit" fi elif (( details )); then + local line find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit" | while IFS= read -r line; do local path="${line#* }" ls -ld -- "$path" done + unset line else find "${find_args[@]}" -printf "%s %p\n" 2>/dev/null | sort -rn | head -n "$limit" fi @@ -748,14 +772,18 @@ findzero() _fd_args+=(. "$dir") if (( delete )); then disp W "Deleting empty files in $dir..." + local f "$_fd" "${_fd_args[@]}" 2>/dev/null | while IFS= read -r f; do printf "%s\n" "$f" rm -f -- "$f" done + unset f elif (( details )); then + local f "$_fd" "${_fd_args[@]}" 2>/dev/null | while IFS= read -r f; do ls -ls -- "$f" done + unset f else "$_fd" "${_fd_args[@]}" 2>/dev/null fi @@ -843,17 +871,23 @@ finddead() _fd_args+=(. "$dir") if (( delete )); then disp W "Deleting dead symlinks in $dir..." + local f "$_fd" "${_fd_args[@]}" 2>/dev/null | while IFS= read -r f; do [[ -e "$f" ]] || { printf "%s\n" "$f"; rm -f -- "$f"; } done + unset f elif (( details )); then + local f "$_fd" "${_fd_args[@]}" 2>/dev/null | while IFS= read -r f; do [[ -e "$f" ]] || ls -ls -- "$f" done + unset f else + local f "$_fd" "${_fd_args[@]}" 2>/dev/null | while IFS= read -r f; do [[ -e "$f" ]] || printf "%s\n" "$f" done + unset f fi elif (( delete )); then disp W "Deleting dead symlinks in $dir..."