大数跨境

ChatGPT 与我的系统清理脚本:谁赢了?

ChatGPT 与我的系统清理脚本:谁赢了? 索引目录
2025-09-01
0
导读:关注【索引目录】服务号,更多精彩内容等你来探索!前段时间,在学习 Bash 脚本时,我尝试深入研究这个主题,并通过解决各种任务(哪怕是最小的任务)来寻求更多练习。

关注【索引目录】服务号,更多精彩内容等你来探索!

前段时间,在学习 Bash 脚本时,我尝试深入研究这个主题,并通过解决各种任务(哪怕是最小的任务)来寻求更多练习。其中一个脚本可以删除临时文件、旧转储文件以及被遗忘已久的项目的 node_modules 文件夹。前几天我偶然发现了它。我在虚拟机上测试了它,虽然可以运行,但代码非常粗糙,而且视觉效果很差。

我当时有什么想法?想看看 ChatGPT 能否做到和我一样(以及做得有多好),而且做得更好。结果很有启发性:AI 在架构方面做得很好,但实际上却试图用几行代码毁掉整个系统。下面我会告诉你它是怎么回事。

任务很简单,你需要根据某些规则自动查找并删除不需要的文件。我以前的脚本简直就是个庞然大物:一堆重复的 find 和 rm -rfa 等笨拙的尝试来处理错误。请不要提前对我做出过多的评判,我当时只是在学习 Bash 及其功能。

我创作中的主要问题

带有变量连接的命令 rm -rf 是俄罗斯轮盘赌游戏(连接是将两个或多个字符串组合成一个)。

路径和脚本中的任何间隙都会默默地“飞过”目标或删除错误的东西。

要更改规则,您需要直接进入代码,一开始没有适当的设置。

该脚本没有记录它删除了什么(或者根本没删除什么?)。它默默地运行着,这总是令人担忧。

我给 ChatGPT 发送了 TOR:“编写一个安全且可自定义的脚本来搜索/删除临时文件、缓存和旧日志。添加一个无法访问的文件夹白名单。添加日志记录。”

前后逐步代码分析

我先来演示一下那个让我感到无比羞愧的“作弊”脚本。分享它真的不容易。以下是
我的版本(为了方便理解,我在写这篇文章之前加了一些评论)。

#!/bin/bash
# If $DIR contains a space, the command will split into two
DIRS="/tmp ~/cache ~/projects/*/node_modules"
# Remove everything at once
for dir in $DIRS; do
    echo "Removing $dir"
    rm -rf "$dir"  # Quotes are here, but the for loop breaks them anyway, right?
done
# Find and delete all .log and .tmp files older than 30 days
find ~/ -name "*.log" -mtime +30 -exec rm {} \; 2>/dev/null
find ~/ -name "*.tmp" -mtime +30 -exec rm {} \; 2>/dev/null
echo "Cleanup done!"

这段代码完全是出于极度的懒惰(毕竟,他本可以“读读互联网”然后做得更好……)。它递归地删除了 node_modules,甚至没有查看文件,还默默地忽略了所有错误( 2>/dev/null ),从而隐藏了现有的权限问题。

ChatGPT 的 Python 版本

我想提前指出,选择 Python 并非偶然,而是经过深思熟虑的选择。我想强调的是,“随身携带的脚本”和经过深思熟虑的可靠工具之间的区别。

ChatGPT 的使命是开发高质量且安全的软件,他们直觉地知道 Bash 并非完成这项工作的合适工具。任何脚本的核心在于安全性,而 Bash 没有内置的安全文件删除机制。安全性实际上取决于正确的转义,以及避免变量意外为空。

我给出的提示是:“编写一个安全且可配置的系统清理脚本。它应该删除旧文件,列出危险目录(例如 /、/home 等)的黑名单,并将其操作记录到文件中。避免直接使用 shell 命令。”

这是 AI 的建议(添加了我的评论和后续编辑)

# cleanup_agent.py
import os
import logging
import time
from pathlib import Path
# === CONFIGURATION ===
TARGETS = [
    {
        "path": os.path.expanduser("~/Downloads"),
        "patterns": ["*.tmp", "*.temp", "*.log"],
        "max_age_days": 7
    },
    {
        "path": os.path.expanduser("~/.cache"),
        "patterns": ["*"],
        "max_age_days": 30
    }
]
# Directories that must never be touched (!)
BLOCKLIST = {
    os.path.expanduser("/"),
    os.path.expanduser("~"),
    os.path.expanduser("~/.ssh"),
}
# Logging setup
logging.basicConfig(
    filename=os.path.expanduser('~/cleanup_agent.log'),
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
def safe_remove(target: Path):
    """Safely remove a file or empty folder with logging"""
    try:
        if target.is_file():
            target.unlink()  # Remove file
            logging.info(f"Removed file: {target}")
        elif target.is_dir():
            target.rmdir()  # Remove empty folder only
            logging.info(f"Removed empty folder: {target}")
    except OSError as e:
        # Log error but don't crash
        logging.error(f"Failed to remove {target}: {e}")
def cleanup_directory(config: dict):
    """Clean a directory based on config"""
    base_dir = Path(config["path"])
    if not base_dir.exists():
        logging.warning(f"Directory not found: {base_dir}")
        return
# Check if directory is in blocklist
    if any(blocked in base_dir.parents for blocked in BLOCKLIST):
        logging.error(f"Attempted cleanup of protected directory: {base_dir}. Aborting.")
        return
current_time = time.time()
    for pattern in config["patterns"]:
        for target in base_dir.rglob(pattern):  # Recursive search
            if not target.exists():
                continue
# Check file/folder age
            age_days = (current_time - target.stat().st_mtime) / (60 * 60 * 24)
            if age_days > config["max_age_days"]:
                safe_remove(target)
if __name__ == "__main__":
    logging.info("=== Cleanup started ===")
    for job in TARGETS:
        cleanup_directory(job)
    logging.info("=== Cleanup finished ===\n")

比较分析

ChatGPT 的正确之处:
尽可能确保脚本的安全。使用 Python 内置方法(unlink、rmdir)消除了 rm -rfdirect 等调用。$HOME 目录下出现了一个黑名单,它完全禁止任何进入 /or 目录的尝试。

增加了可定制性。与其硬编码,不如采用字典列表形式的配置,其中包含目标。需要清理其他文件夹或更改“年龄”?只需编辑列表即可,无需更改代码。在我看来,这是一个正确且有效的解决方案。

该脚本现在维护一个完整的日志文件。现在您不仅可以看到删除的内容,还可以了解出错的原因。
使用 pathlib.Path 代替字符串连接,这更适合处理路径。它会自动处理不同的操作系统并转义特殊字符。

ChatGPT 不太正确的地方(在我看来,如果我错了,请纠正我)

递归搜索有点危险。最初,AI 使用 base_dir.rglob(' ') 来查找 ~/.cache 中的模式“ ”。这字面意思是:“递归遍历缓存中的所有内容,并检查每个文件的使用期限”。对于缓存目录来说,由于其中包含大量小文件,这很容易导致极其漫长且无用的工作。为了进行如此激进的清理,我建议添加一个最小使用期限的条件。

模仿安全性。函数 safe_remove 仅在文件夹为空时尝试删除文件夹。这很安全,但对 node_modules 来说完全没用。对于“非空”目录,脚本会直接忽略它们。最好在日志中明确指定这一点。

这不是最实用的模板。模板“ ~/.cache ”太宽了。更正确的格式应该是:[' .bin', 'cache/ ', 'thumbnails/ '] 等。

可以得出什么结论:ChatGPT 将一个质量低下且略带危险的 Bash 脚本变成了一个几乎可以用于生产的实用程序,并附带配置和日志。但盲目地相信“所有事物和所有人”的递归遍历很容易导致系统瘫痪。AI 可以完美地构建和保护代码,但它似乎缺乏对“我到底应该清理什么”的具体理解。作为生成的辅助工具,它是必不可少的,但你需要充分了解相关内容并非常仔细地监控生成的代码,以避免危险的后果。

使用示例

与往常一样,脚本的说明在文章中(也许有人会需要它?)

将代码保存到文件 cleanup_agent.py。
我们编辑所需任务的配置目标。需要每周清理一次下载内容 - 请。需要从 pycache 中清理项目 - 我们添加了一条规则。
让我们启动它并查看日志。

# Make the script executable
chmod +x cleanup_agent.py
# Run the script
python3 cleanup_agent.py

检查日志输出

tail -f ~/cleanup_agent.log
The output in the log will be something like this:
2025-08-19 11:05:32,123 - INFO - === Cleanup started ===
2025-08-19 11:05:32,456 - INFO - Removed file: /home/user/Downloads/old_report.tmp
2025-08-19 11:05:33,001 - ERROR - Failed to remove /home/user/.cache/some_file: [Errno 13] Permission denied
2025-08-19 11:05:33,002 - INFO - === Cleanup finished ===

提示:仅当您确实需要接触受保护的路径时才使用 sudo 运行。否则,请保留权限错误信息。


关注【索引目录】服务号,更多精彩内容等你来探索!


【声明】内容源于网络
0
0
索引目录
索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
内容 444
粉丝 0
索引目录 索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
总阅读12
粉丝0
内容444