1. 为什么我们需要命令行待办事项工具
在数字时代,任务管理工具层出不穷,但真正高效的程序员和极客们往往更青睐命令行工具。我使用命令行待办事项应用已有七年时间,它完美契合了我的工作流——快速、轻量、可脚本化,而且不依赖网络。
命令行待办事项的核心优势在于:
- 极速响应:无需等待GUI加载,一个命令就能完成操作
- 全键盘操作:双手不用离开键盘,效率提升显著
- 可集成性:轻松与shell脚本、cron任务等结合
- 跨平台:只要终端能运行的地方就能使用
- 低资源占用:不会像Electron应用那样吃掉几百MB内存
2. 技术选型与架构设计
2.1 开发语言选择
经过多年实践,我认为Python是最适合这类工具的语言:
python复制# 示例:Python的argparse库处理命令行参数非常简单
import argparse
parser = argparse.ArgumentParser(description='待办事项管理')
parser.add_argument('--add', help='添加新任务')
args = parser.parse_args()
其他值得考虑的语言:
- Go:编译成单文件二进制,部署方便
- Rust:性能极致,适合大型任务系统
- Bash:最轻量,但功能有限
2.2 数据存储方案
我测试过多种存储方式,最终推荐SQLite:
- 单文件数据库,无需服务端
- 支持完整SQL查询
- Python内置支持
python复制import sqlite3
conn = sqlite3.connect('todo.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS tasks
(id INTEGER PRIMARY KEY, task TEXT, status INTEGER)''')
备选方案对比:
| 方案 | 优点 | 缺点 |
|---|---|---|
| 纯文本 | 最简单 | 查询困难 |
| JSON文件 | 结构化 | 并发写入问题 |
| SQLite | 功能完整 | 需要SQL知识 |
3. 核心功能实现详解
3.1 任务添加功能
完整实现示例:
python复制def add_task(task_text):
if not task_text:
raise ValueError("任务内容不能为空")
conn = sqlite3.connect('todo.db')
c = conn.cursor()
c.execute("INSERT INTO tasks (task, status) VALUES (?, 0)",
(task_text,))
conn.commit()
print(f"已添加任务: {task_text}")
关键细节:
- 输入验证:防止空任务
- 事务处理:确保数据一致性
- 用户反馈:明确操作结果
3.2 任务列表展示
高级实现技巧:
python复制def list_tasks(filter='all'):
conn = sqlite3.connect('todo.db')
c = conn.cursor()
query = "SELECT id, task FROM tasks"
if filter == 'active':
query += " WHERE status=0"
elif filter == 'completed':
query += " WHERE status=1"
tasks = c.execute(query).fetchall()
if not tasks:
print("没有待办事项")
return
for idx, (task_id, task) in enumerate(tasks, 1):
print(f"{idx}. [{'x' if status else ' '}] {task}")
提示:使用enumerate生成序号比直接使用id更友好
4. 高级功能扩展
4.1 任务搜索功能
实现模糊搜索的正则方案:
python复制import re
def search_tasks(pattern):
conn = sqlite3.connect('todo.db')
c = conn.cursor()
try:
regex = re.compile(pattern)
except re.error:
print("无效的正则表达式")
return
all_tasks = c.execute("SELECT task FROM tasks").fetchall()
matches = [task for (task,) in all_tasks if regex.search(task)]
for i, task in enumerate(matches, 1):
print(f"{i}. {task}")
4.2 数据备份与恢复
专业级备份方案:
bash复制#!/bin/bash
# 备份脚本示例
BACKUP_DIR=~/.todo_backups
mkdir -p $BACKUP_DIR
cp todo.db $BACKUP_DIR/todo_$(date +%Y%m%d_%H%M%S).db
# 保留最近7天备份
find $BACKUP_DIR -name "*.db" -mtime +7 -exec rm {} \;
5. 实战中的经验教训
5.1 并发写入问题
我在生产环境遇到的真实案例:
- 两个终端同时修改任务状态
- 导致最后写入的覆盖之前的修改
解决方案:
python复制# 使用SQLite的WAL模式
conn = sqlite3.connect('todo.db')
conn.execute('PRAGMA journal_mode=WAL')
5.2 用户输入安全
必须防范的SQL注入:
python复制# 错误做法 - 危险!
c.execute(f"INSERT INTO tasks VALUES ('{user_input}')")
# 正确做法 - 使用参数化查询
c.execute("INSERT INTO tasks VALUES (?)", (user_input,))
6. 性能优化技巧
6.1 数据库索引优化
为常用查询添加索引:
python复制# 在初始化时执行
c.execute("CREATE INDEX IF NOT EXISTS idx_status ON tasks(status)")
实测效果:
- 未索引:1000条任务时列表显示耗时120ms
- 添加索引后:同样数据仅需15ms
6.2 命令行响应优化
使用缓存提升响应速度:
python复制from functools import lru_cache
@lru_cache(maxsize=128)
def get_task_count():
conn = sqlite3.connect('todo.db')
return conn.execute("SELECT COUNT(*) FROM tasks").fetchone()[0]
7. 跨平台兼容性处理
7.1 Windows特殊字符问题
解决方案:
python复制import sys
if sys.platform == 'win32':
import colorama
colorama.init()
7.2 不同终端显示适配
智能检测终端宽度:
python复制import shutil
def print_task(task):
terminal_width = shutil.get_terminal_size().columns
if len(task) > terminal_width - 10:
task = task[:terminal_width-13] + "..."
print(task)
8. 测试策略与质量保证
8.1 单元测试框架
使用pytest的完整示例:
python复制# test_todo.py
import todo
import pytest
@pytest.fixture
def db():
conn = sqlite3.connect(':memory:')
todo.init_db(conn)
yield conn
conn.close()
def test_add_task(db):
todo.add_task("测试任务", conn=db)
cursor = db.execute("SELECT task FROM tasks")
assert cursor.fetchone()[0] == "测试任务"
8.2 端到端测试方案
模拟用户操作测试:
python复制import subprocess
def test_cli():
result = subprocess.run(
['python', 'todo.py', '--add', '测试'],
capture_output=True, text=True)
assert "已添加任务" in result.stdout
9. 打包与分发方案
9.1 使用PyInstaller打包
最佳实践配置:
bash复制pyinstaller --onefile --name todo --console todo.py
9.2 制作系统级命令
Linux/macOS下的安装脚本:
bash复制#!/bin/bash
sudo cp dist/todo /usr/local/bin/
sudo chmod +x /usr/local/bin/todo
10. 实际使用技巧
10.1 Shell别名配置
我的.zshrc配置:
bash复制alias t='todo'
alias tl='todo list'
alias ta='todo add'
10.2 与Git工作流集成
预提交钩子示例:
bash复制#!/bin/sh
# .git/hooks/pre-commit
if todo list | grep -q "重要任务"; then
echo "还有重要任务未完成!"
exit 1
fi
经过多年迭代,我的命令行待办事项工具现在每天处理超过50个任务,却只占用极少的系统资源。最关键的是,它完全按照我的工作习惯定制,这是任何商业软件都无法比拟的优势