-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcleanup-junk-files.sh
More file actions
executable file
·159 lines (139 loc) · 4.91 KB
/
cleanup-junk-files.sh
File metadata and controls
executable file
·159 lines (139 loc) · 4.91 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/sh
########################################################################
# cleanup-junk-files.sh: Clean Up Junk Files
#
# Description:
# This script removes common junk files from a specified directory.
# It targets files like .DS_Store, ._* AppleDouble files, temporary
# Unix files ending with '.un~', and __pycache__ directories.
#
# Author: id774 (More info: http://id774.net)
# Source Code: https://github.com/id774/scripts
# License: The GPL version 3, or LGPL version 3 (Dual License).
# Contact: idnanashi@gmail.com
#
# Usage:
# ./cleanup-junk-files.sh <target_directory>
# Example:
# ./cleanup-junk-files.sh /path/to/directory
#
# Notes:
# - This script will recursively delete the specified junk files in the target directory.
# - Use with caution and ensure that the target directory is correct.
# - It is advisable to perform a dry run or backup important files before execution.
#
# Version History:
# v2.1 2025-12-20
# Guard against home directory target by resolving and comparing physical paths.
# v2.0 2025-12-15
# Guard against root directory target, fix '*.un~' match, add type filters,
# and use batched '-exec ... +' for efficiency.
# v1.9 2025-06-23
# Unified usage output to display full script header and support common help/version options.
# v1.8 2025-04-13
# Unify log level formatting using [INFO], [WARN], and [ERROR] tags.
# v1.7 2025-03-22
# Unify usage information by extracting help text from header comments.
# v1.6 2025-03-16
# Encapsulated all logic in functions and introduced main function.
# v1.5 2025-03-13
# Redirected error messages to stderr for better logging and debugging.
# v1.4 2024-01-07
# Updated command existence and execution permission checks
# using a common function for enhanced reliability and maintainability.
# v1.3 2023-12-23
# Refactored for POSIX compliance. Replaced Bash-specific syntax
# with POSIX standard commands and structures. Enhanced portability
# and compatibility across different UNIX-like systems.
# v1.2 2023-12-20
# Added feature to remove __pycache__ directories.
# v1.1 2023-12-06
# Refactored for improved readability, added detailed comments and notes.
# v1.0 2016-08-05
# Initial release.
#
########################################################################
# Display full script header information extracted from the top comment block
usage() {
awk '
BEGIN { in_header = 0 }
/^#{10,}$/ { if (!in_header) { in_header = 1; next } else exit }
in_header && /^# ?/ { print substr($0, 3) }
' "$0"
exit 0
}
# Check if required commands are available and executable
check_commands() {
for cmd in "$@"; do
cmd_path=$(command -v "$cmd" 2>/dev/null)
if [ -z "$cmd_path" ]; then
echo "[ERROR] Command '$cmd' is not installed. Please install $cmd and try again." >&2
exit 127
elif [ ! -x "$cmd_path" ]; then
echo "[ERROR] Command '$cmd' is not executable. Please check the permissions." >&2
exit 126
fi
done
}
# Resolve a directory path to an absolute physical path
resolve_dir_path() {
dir="$1"
(
cd "$dir" 2>/dev/null || exit 1
pwd -P 2>/dev/null || pwd
)
}
# Refuse dangerous target such as root directory
guard_target_dir() {
target="$1"
target_real=$(resolve_dir_path "$target")
if [ -z "$target_real" ]; then
echo "[ERROR] Failed to resolve target directory: $target" >&2
exit 1
fi
if [ "$target_real" = "/" ]; then
echo "[ERROR] Refuse to operate on '/'" >&2
exit 1
fi
if [ -n "$HOME" ]; then
home_real=$(resolve_dir_path "$HOME")
if [ -n "$home_real" ] && [ "$target_real" = "$home_real" ]; then
echo "[ERROR] Refuse to operate on HOME directory: $home_real" >&2
exit 1
fi
fi
}
# Perform cleanup of junk files
cleanup_junk_files() {
echo "[INFO] Cleaning up junk files in $1..."
echo "[INFO] Removing ._* AppleDouble files..."
find "$1" -type f -name '._*' -exec rm -f {} +
echo "[INFO] Removing .DS_Store files..."
find "$1" -type f -name '.DS_Store' -exec rm -f {} +
echo "[INFO] Removing temporary Unix files ending with '.un~'..."
find "$1" -type f -name '*.un~' -exec rm -f {} +
echo "[INFO] Removing __pycache__ directories..."
find "$1" -type d -name '__pycache__' -exec rm -rf {} +
echo "[INFO] Cleanup completed."
}
# Main entry point of the script
main() {
case "$1" in
-h|--help|-v|--version) usage ;;
esac
# Check if rm and find commands exist
check_commands rm find
if [ "$#" -eq 0 ]; then
usage
fi
if [ -d "$1" ]; then
guard_target_dir "$1"
cleanup_junk_files "$1"
else
echo "[ERROR] Directory '$1' is not found." >&2
exit 1
fi
return 0
}
# Execute main function
main "$@"