本文目录导读:

“实用脚本”的核心在于:能用一行命令解决繁琐问题,并考虑各种意外情况,一个好的脚本不仅仅是“能跑”,更是“跑得稳”、“易复用”。
下面我为你提供一个模板化的编写思路,并用一个具体例子(批量重命名文件)来拆解实战。
第一部分:万能脚本骨架(Bash/Python)
一个好的脚本通常包含以下几个模块:
- Shebang (解释器声明)
- 参数解析与帮助信息
- 输入校验
- 核心逻辑
- 错误处理
- 日志输出
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个“必杀技”
- 永远不要信任输入:假设用户给了一个不存在的路径、空的目录,要优雅地处理(
exit 1)并给出提示。 - 加锁:如果一个脚本只能同时运行一个实例(例如备份脚本),在开头加锁:
#!/bin/bash LOCKFILE="/tmp/my_script.lock" exec 200>$LOCKFILE flock -n 200 || { echo "脚本已在运行,退出中..."; exit 1; } # ... 实际逻辑 ... - 善用
set -e和set -x:set -e:脚本中只要有一行命令出错(非零退出码),立刻停止执行,防止造成更大破坏。set -x:打印执行的每一行命令,用于调试(生产环境慎用)。
- 提供
--help/-h:这是评分最高的习惯,只需输出Usage: ...,用户会感激你。 - 把“可配置参数”放在文件开头:这样以后只需要修改开头的几个变量就行,不用去逻辑里找。
怎么写一个脚本?
- 想清楚你要自动化什么(筛选文件?格式化输出?定期清理?)
- 选语言:Linux系统交互 → Bash;跨平台/复杂数据结构 → Python
- 套上面给的骨架:参数解析 → 校验 → 循环处理 → 错误处理
- 测试:先在一个测试目录里跑,不要直接在
/home/important_data下跑。 - 添加使用说明:任何你自己3个月后还会看得懂的东西。
如果你有一个具体的需求想写成脚本,每天凌晨自动备份mysql数据库并发送邮件”,可以直接把场景发给我,我帮你写一个可直接运行的版本。