实用脚本怎么写?

wen 实用脚本 9

本文目录导读:

实用脚本怎么写?

  1. 第一部分:万能脚本骨架(Bash/Python)
  2. 第二部分:3个超实用场景 + 极简代码
  3. 第三部分:写好脚本的5个“必杀技”
  4. 总结:怎么写一个脚本?

“实用脚本”的核心在于:能用一行命令解决繁琐问题,并考虑各种意外情况,一个好的脚本不仅仅是“能跑”,更是“跑得稳”、“易复用”。

下面我为你提供一个模板化的编写思路,并用一个具体例子(批量重命名文件)来拆解实战。


第一部分:万能脚本骨架(Bash/Python)

一个好的脚本通常包含以下几个模块:

  1. Shebang (解释器声明)
  2. 参数解析与帮助信息
  3. 输入校验
  4. 核心逻辑
  5. 错误处理
  6. 日志输出

Shell 脚本 (Linux/Mac) 实战模板

假设我们需要写一个脚本,把当前目录下的 .txt 文件批量加上日期前缀。

#!/bin/bash
# 上面这行必须要有,告诉系统用 Bash 执行
# --- 配置区 (方便以后改) ---
SOURCE_DIR="."          # 默认当前目录
FILE_PATTERN="*.txt"    # 匹配模式
DATE_FORMAT="%Y%m%d"    # 日期格式
# --- 帮助信息 ---
show_help() {
# 这里的 cat << EOF 是多行输出
    cat << EOF
用法: $0 [选项]
批量给当前目录下的文件添加日期前缀
选项:
  -d, --dir      指定目录 (默认: .)
  -h, --help     显示此帮助信息
示例:
  $0              # 添加所有txt文件日期前缀
  $0 -d /path     # 对指定目录操作
EOF
exit 0
}
# --- 参数解析 (使用 getopt) ---
# 简单的参数接收
while [[ "$#" -gt 0 ]]; do
    case $1 in
        -h|--help) show_help ;;
        -d|--dir) SOURCE_DIR="$2"; shift ;;  # shift 用于移动参数列表
        *) echo "未知参数: $1"; show_help; exit 1 ;;
    esac
    shift
done
# --- 输入校验 ---
if [ ! -d "$SOURCE_DIR" ]; then
    echo "错误:目录 '$SOURCE_DIR' 不存在!"
    exit 1
fi
cd "$SOURCE_DIR" || exit 1  # 如果cd失败,直接退出
# 检查是否有匹配的文件
# 这里用 shopt -s nullglob 让没找到文件时返回空数组而不是通配符本身
shopt -s nullglob
FILES=( $FILE_PATTERN )
if [ ${#FILES[@]} -eq 0 ]; then
    echo "在 $SOURCE_DIR 中没有找到 $FILE_PATTERN 文件,脚本退出。"
    exit 0
fi
# --- 核心逻辑 ---
CURRENT_DATE=$(date +"$DATE_FORMAT")
echo "开始处理 ${#FILES[@]} 个文件..."
for file in "${FILES[@]}"; do
    # 防止重复添加 (如果已经有日期前缀则跳过)
    if [[ "$file" =~ ^[0-9]{8}_.* ]]; then
        echo " [跳过] $file (已有前缀)"
        continue
    fi
    new_name="${CURRENT_DATE}_${file}"
    # --- 错误处理 (重命名失败时处理) ---
    if mv "$file" "$new_name" 2>/dev/null; then
        echo " [成功] $file -> $new_name"
    else
        echo " [失败] 无法重命名 '$file' (可能权限不足?)" >&2
        # >&2 表示把错误消息输出到标准错误流
    fi
done
echo "处理完成!"

Python 脚本 (跨平台,Windows/Mac/Linux) 实战模板

Python 在复杂的文本处理、调用API、Excel处理方面更强。

# -*- coding: utf-8 -*-
# 支持中文注释
import os
import sys
import argparse  # 标准库,专门用来写命令行参数
from datetime import datetime
# --- 核心函数 ---
def batch_rename(target_dir=".", pattern=".txt"):
    # 获取当前日期
    today = datetime.now().strftime("%Y%m%d")
    # 列出所有匹配的文件
    try:
        files = [f for f in os.listdir(target_dir) if f.endswith(pattern)]
    except FileNotFoundError:
        print(f"错误:目录 '{target_dir}' 不存在!")
        sys.exit(1)  # 非零退出码表示错误
    if not files:
        print(f"在 {target_dir} 中没有找到 *{pattern} 文件。")
        return
    print(f"找到 {len(files)} 个文件,开始处理...")
    for file in files:
        # 跳过已经带日期前缀的
        if file.startswith(today + "_"):
            print(f" [跳过] {file}")
            continue
        old_path = os.path.join(target_dir, file)
        new_name = f"{today}_{file}"
        new_path = os.path.join(target_dir, new_name)
        try:
            os.rename(old_path, new_path)
            print(f" [成功] {file} -> {new_name}")
        except PermissionError:
            print(f" [失败] 权限不足: {file}")
        except Exception as e:
            # 捕获其他未知异常
            print(f" [失败] 未知错误: {e}")
# --- 主入口 (参数解析) ---
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="给文件添加日期前缀 (Python版)")
    parser.add_argument("-d", "--dir", type=str, default=".", help="目标目录 (默认当前目录)")
    parser.add_argument("-p", "--pattern", type=str, default=".txt", help="文件后缀 (默认 .txt)")
    args = parser.parse_args()  # 自动解析 sys.argv
    # 调用核心逻辑
    batch_rename(args.dir, args.pattern)

第二部分:3个超实用场景 + 极简代码

下面是一些“拿来即用”的脚本,适合日常快速解决问题。

场景1:一键压缩并备份项目 (tar + 日期)

#!/bin/bash
# 文件名: backup.sh
TIMESTAMP=$(date +"%Y%m%d_%H%M")
BACKUP_NAME="project_backup_${TIMESTAMP}.tar.gz"
tar -czf "$BACKUP_NAME" --exclude="node_modules" --exclude=".git" .
echo "备份完成: $BACKUP_NAME"

场景2:批量重命名图片 (去掉空格,改为下划线)

#!/bin/bash
# 处理所有 jpg png 文件
for file in *.{jpg,png,webp}; do
    # 只处理存在且包含空格的文件
    if [[ -f "$file" && "$file" == *" "* ]]; then
        new_name="${file// /_}"  # 把所有空格替换为下划线
        mv "$file" "$new_name"
        echo "重命名: $file -> $new_name"
    fi
done

场景3:命令行快速查找并杀死进程

#!/bin/bash
# 文件名: killport.sh
# 用法: ./killport.sh 3000
PORT=$1
if [ -z "$PORT" ]; then
    echo "请提供端口号, $0 8080"
    exit 1
fi
# 查找占用端口的PID
PID=$(lsof -ti:$PORT)  # -t 只输出PID
if [ -z "$PID" ]; then
    echo "端口 $PORT 未被占用。"
else
    echo "发现进程 PID: $PID,正在杀死..."
    kill -9 $PID
    echo "已杀死端口 $PORT 的进程。"
fi

第三部分:写好脚本的5个“必杀技”

  1. 永远不要信任输入:假设用户给了一个不存在的路径、空的目录,要优雅地处理(exit 1)并给出提示。
  2. 加锁:如果一个脚本只能同时运行一个实例(例如备份脚本),在开头加锁:
    #!/bin/bash
    LOCKFILE="/tmp/my_script.lock"
    exec 200>$LOCKFILE
    flock -n 200 || { echo "脚本已在运行,退出中..."; exit 1; }
    # ... 实际逻辑 ...
  3. 善用 set -eset -x
    • set -e:脚本中只要有一行命令出错(非零退出码),立刻停止执行,防止造成更大破坏。
    • set -x:打印执行的每一行命令,用于调试(生产环境慎用)。
  4. 提供 --help / -h:这是评分最高的习惯,只需输出 Usage: ...,用户会感激你。
  5. 把“可配置参数”放在文件开头:这样以后只需要修改开头的几个变量就行,不用去逻辑里找。

怎么写一个脚本?

  1. 想清楚你要自动化什么(筛选文件?格式化输出?定期清理?)
  2. 选语言:Linux系统交互 → Bash;跨平台/复杂数据结构 → Python
  3. 套上面给的骨架:参数解析 → 校验 → 循环处理 → 错误处理
  4. 测试:先在一个测试目录里跑,不要直接在 /home/important_data 下跑。
  5. 添加使用说明:任何你自己3个月后还会看得懂的东西。

如果你有一个具体的需求想写成脚本,每天凌晨自动备份mysql数据库并发送邮件”,可以直接把场景发给我,我帮你写一个可直接运行的版本。

抱歉,评论功能暂时关闭!