用 Python 写一个顺手的命令行小工具
argparse 其实没那么难,难的是想清楚“这个工具应该有多小”。
我每天都会做一件很无聊的事:把临时想到的句子、读到的段落、待办事项,追加到同一个 Markdown 文件里。用编辑器当然可以,但每次都要切窗口、找文件、滚到底部,久而久之就不想记了。
于是写了一个十几行的命令,叫 note。
先把需求缩小
一开始我想得很复杂:分类、搜索、同步、导出……最后只留下一个动作:
note 今天读完了《CSS 世界》第三章 -t 阅读 -t css它做三件事:把内容拼成一行、加上标签、追加到 notes.md。不做的部分同样重要:不建数据库、不联网、不弹提示。
用 argparse 描述接口
from __future__ import annotations
import argparse
from pathlib import Path
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="note",
description="把零散的想法追加到一个 Markdown 文件里。",
)
parser.add_argument("text", nargs="*", help="要记录的内容")
parser.add_argument("-t", "--tag", action="append", default=[], metavar="TAG",
help="标签,可以重复使用")
parser.add_argument("-f", "--file", type=Path, default=Path("notes.md"),
metavar="PATH", help="目标文件,默认 ./notes.md")
return parser
def main() -> None:
args = build_parser().parse_args()
line = " ".join(args.text).strip()
if not line:
raise SystemExit("没有内容可记,试试:note 今天天气很好")
if not args.file.parent.exists():
args.file.parent.mkdir(parents=True, exist_ok=True)
tags = " ".join(f"#{tag.lstrip('#')}" for tag in args.tag)
with args.file.open("a", encoding="utf-8") as handle:
handle.write(f"- {line} {tags}".rstrip() + "\n")
if __name__ == "__main__":
main()action="append" 让 -t 可以重复出现,type=Path 直接把字符串转成路径对象,nargs="*" 则允许内容里带空格而不用加引号。
让 --help 说人话
argparse 生成的帮助文本默认很干。加三样东西就够了:
prog:显示命令名,而不是__main__.py。description:一句话说清它是干什么的。- 每个参数的
help与metavar:让占位符看起来像人话。
usage: note [-h] [-t TAG] [-f PATH] [text ...]
把零散的想法追加到一个 Markdown 文件里。
positional arguments:
text 要记录的内容
options:
-h, --help show this help message and exit
-t TAG, --tag TAG 标签,可以重复使用
-f PATH, --file PATH 目标文件,默认 ./notes.md让它可以被直接调用
把文件放到 ~/bin/note(或任何在 PATH 里的目录),在开头加上 #!/usr/bin/env python3,然后赋予执行权限:
chmod +x ~/bin/noteWindows 上可以把它放进一个 .cmd 包装器,或者干脆用 python note.py 的别名。我用的是 PowerShell 的 profile:
function note { python "$HOME\tools\note.py" @args }几条自己总结的规则
- 参数不超过五个。 超过就说明这个工具承担了太多职责,该拆了。
- 默认值要安全。 默认写入
notes.md,而不是覆盖某个已有文件。 - 输出要能接管道。 需要列出内容时,一行一条,不加装饰性字符。
- 错误信息要给出下一步。 与其说“参数错误”,不如说“没有内容可记,试试:note 今天天气很好”。
最后
这个工具现在只有二十来行,但我每天都会用。它没有配置文件,没有插件系统,也没有 README——因为使用方式就写在 --help 里。
写小工具最快乐的时刻,是发现自己已经想不起来没有它的时候是怎么干活的。