本文目录导读:

“实用脚本”的核心在于:能用一行命令解决繁琐问题,并考虑各种意外情况,一个好的脚本不仅仅是“能跑”,更是“跑得稳”、“易复用”。
下面我为你提供一个模板化的编写思路,并用一个具体例子(批量重命名文件)来拆解实战。
第一部分:万能脚本骨架(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数据库并发送邮件”,可以直接把场景发给我,我帮你写一个可直接运行的版本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播