自动化脚本怎么写才不翻车?新手避坑指南来了

一人公司实验室
2026-05-06 02:37
阅读 1011

大家好,我是一名从培训班出来的前端开发者。记得刚入行那会儿,每天被各种重复任务折磨得够呛:改配置、批量重命名、自动部署……老板还总说“能不能搞个脚本来自动化一下?”我一脸懵——脚本是啥?怎么写?写了会不会删库跑路?

后来我花了不少时间摸索,踩了无数坑,终于搞明白了自动化脚本的核心逻辑。今天我就用最接地气的方式,带零基础的你从零开始写出安全、高效、可维护的自动化脚本。这篇文章不讲虚的,全是实战干货,尤其会重点解决新手最头疼的两个问题:资源管理不当导致系统卡死,以及运营流程混乱引发线上事故


一、自动化脚本到底是什么?

简单说,自动化脚本就是让电脑替你干重复、枯燥的活

比如:

  • 每天早上8点自动备份数据库
  • 批量压缩1000张图片
  • 发布新版本时自动构建、测试、部署
  • 定时清理服务器上的临时文件

这些事如果手动做,又慢又容易出错。而脚本一旦写好,就能一键执行,甚至定时自动跑。

💡 我当初学的时候,以为脚本就是写一堆命令堆在一起。结果第一次写的脚本没加错误判断,不小心把生产环境的配置文件给覆盖了……还好有备份!从此我明白:写脚本不是图快,而是图稳


二、环境准备:5分钟搭好开发环境

我们用 Node.js + JavaScript 来写脚本(因为前端同学都熟悉,而且生态强大)。如果你还没装 Node,请按以下步骤操作:

1. 安装 Node.js

  • 访问 https://nodejs.org
  • 下载 LTS 版本(长期支持版,更稳定)
  • 安装时一路默认选项即可

2. 验证安装

打开终端(Mac/Linux 用 Terminal,Windows 用 PowerShell 或 CMD),输入:

node -v
npm -v

如果显示版本号(如 v18.17.0),说明安装成功!

3. 创建项目目录

mkdir my-auto-script
cd my-auto-script
npm init -y

这会在当前目录生成一个 package.json 文件,用于管理脚本依赖。


三、核心概念:资源与运营的平衡术

很多新手写脚本只关注“功能实现”,却忽略了两个致命问题:

📌 什么是“资源”?

在脚本中,“资源”指的是:

  • 内存
  • CPU 使用率
  • 磁盘 I/O(读写速度)
  • 网络带宽
  • 文件句柄(打开的文件数量)

错误示范:一次性读取10GB的日志文件到内存 → 内存爆了,系统卡死!

正确做法:用流式读取(Stream),一次只处理一小块数据。

📌 什么是“运营”?

“运营”在这里指脚本的可维护性、可观测性和可恢复性,包括:

  • 日志记录(方便排查问题)
  • 错误处理(出错了别直接崩)
  • 参数配置(不同环境能灵活切换)
  • 回滚机制(万一出错能快速恢复)

最佳实践口诀
小步快跑,资源节制;日志齐全,运营无忧。


四、实战:写一个安全的文件清理脚本

我们来做一个实用场景:自动清理30天前的临时文件

步骤1:安装必要工具

npm install fs-extra chalk dayjs
  • fs-extra:增强版文件操作库(比原生 fs 更友好)
  • chalk:给控制台输出加颜色(方便区分信息/警告/错误)
  • dayjs:轻量级日期处理库

步骤2:编写脚本 clean-temp.js

// clean-temp.js
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const dayjs = require('dayjs');

// 配置项(方便后续调整)
const CONFIG = {
  TEMP_DIR: './temp',        // 临时文件目录
  DAYS_TO_KEEP: 30,          // 保留最近30天的文件
  MAX_CONCURRENT: 5,         // 最大并发数(控制资源占用!)
};

async function cleanTempFiles() {
  console.log(chalk.blue('🚀 开始清理临时文件...'));

  try {
    // 1. 检查目录是否存在
    if (!await fs.pathExists(CONFIG.TEMP_DIR)) {
      console.log(chalk.yellow('⚠️ 临时目录不存在,跳过清理'));
      return;
    }

    // 2. 获取所有文件
    const files = await fs.readdir(CONFIG.TEMP_DIR);
    if (files.length === 0) {
      console.log(chalk.green('✅ 临时目录为空,无需清理'));
      return;
    }

    // 3. 过滤出需要删除的旧文件
    const cutoffDate = dayjs().subtract(CONFIG.DAYS_TO_KEEP, 'day');
    const filesToDelete = [];

    for (const file of files) {
      const filePath = path.join(CONFIG.TEMP_DIR, file);
      const stats = await fs.stat(filePath);
      
      // 跳过目录(只处理文件)
      if (stats.isDirectory()) continue;
      
      // 判断是否超过保留天数
      if (dayjs(stats.mtime).isBefore(cutoffDate)) {
        filesToDelete.push(filePath);
      }
    }

    // 4. 安全删除(限制并发,避免资源耗尽)
    if (filesToDelete.length === 0) {
      console.log(chalk.green('✅ 没有需要清理的旧文件'));
      return;
    }

    console.log(chalk.yellow(`🗑️  共发现 ${filesToDelete.length} 个旧文件,开始删除...`));

    // 分批删除,控制并发
    const batches = [];
    for (let i = 0; i < filesToDelete.length; i += CONFIG.MAX_CONCURRENT) {
      batches.push(filesToDelete.slice(i, i + CONFIG.MAX_CONCURRENT));
    }

    for (const batch of batches) {
      await Promise.all(
        batch.map(async (filePath) => {
          try {
            await fs.remove(filePath);
            console.log(chalk.gray(`  已删除: ${filePath}`));
          } catch (err) {
            console.error(chalk.red(`  删除失败: ${filePath} - ${err.message}`));
          }
        })
      );
      // 每批之间稍作休息,降低系统压力
      await new Promise(resolve => setTimeout(resolve, 100));
    }

    console.log(chalk.green('✅ 清理完成!'));

  } catch (error) {
    console.error(chalk.red('❌ 清理过程中发生错误:'), error.message);
    // 运营关键:错误也要记录到日志文件!
    await fs.appendFile('cleanup-error.log', `${new Date().toISOString()} - ${error.stack}\n`);
  }
}

// 执行脚本
cleanTempFiles();

步骤3:测试脚本

  1. 创建测试目录:
mkdir temp
echo "test" > temp/file1.txt
touch -d "2020-01-01" temp/old-file.txt  # Linux/Mac 创建旧文件
  1. 运行脚本:
node clean-temp.js

你会看到彩色输出,并且只有旧文件被删除!


五、新手常犯的5个致命错误(附解决方案)

错误 后果 解决方案
不加错误处理 脚本崩溃,任务中断 try/catch 包裹主逻辑
一次性加载大量数据 内存溢出,系统卡死 使用流(Stream)或分页处理
硬编码路径/参数 不同环境无法复用 把配置抽成 CONFIG 对象
没有日志记录 出问题无法排查 至少记录关键步骤和错误
权限过高 误删重要文件 脚本只操作指定目录,避免用 root 运行

🛑 血泪教训:我见过同事写了个 rm -rf /tmp/* 的 shell 脚本,结果手抖写成 rm -rf / tmp/*(多了个空格)……整个系统根目录被清空!所以永远不要在脚本里写危险命令而不加确认


六、进阶建议:让你的脚本更专业

1. 加上命令行参数

process.argvminimist 库支持动态传参:

node clean-temp.js --days=7 --dir=/var/log

2. 添加定时任务(Cron)

Linux/Mac 用 crontab -e 添加:

# 每天凌晨2点执行
0 2 * * * cd /your/script/path && node clean-temp.js >> cleanup.log 2>&1

3. 输出结构化日志

把日志写成 JSON 格式,方便后续分析:

{"time":"2023-10-01T02:00:00Z","action":"delete","file":"/temp/old.log","status":"success"}

4. 单元测试不能少

用 Jest 写简单测试,确保逻辑正确:

test('should not delete recent files', async () => {
  // 创建一个1天前的文件
  // 运行脚本
  // 断言文件仍然存在
});

七、下一步学什么?

如果你已经掌握了基础脚本编写,建议按以下路径深入:

  1. 学 Shell 脚本:Linux 系统运维必备(bash/zsh
  2. 掌握任务调度:了解 cronsystemd timer、Airflow 等工具
  3. 学习 CI/CD:把脚本集成到 GitLab CI / GitHub Actions 中
  4. 探索自动化框架:如 Python 的 schedule、Node.js 的 node-cron

💬 最后送大家一句话:自动化不是为了替代人,而是让人去做更有价值的事。写好每一个脚本,都是在为未来的自己节省时间。

现在,打开你的终端,新建一个 .js 文件,写下你的第一行自动化代码吧!遇到问题随时回来翻这篇指南——毕竟,我也是这么一步步走过来的。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝