高效开发者的日常脚本工具箱

本文分享了作者十多年来积累的实用Shell脚本,涵盖剪贴板管理、文件操作、网络工具、文本处理、进程管理等开发场景,帮助提升日常工作效率的自动化工具集合。

我经常使用的自写脚本

作者:Evan Hahn 发布日期:2025年10月22日

在我维护dotfiles的十多年间,我写了很多小型的shell脚本。以下是我个人最喜欢的一些脚本清单。

剪贴板

copypasta是系统剪贴板管理器的简单封装,比如macOS上的pbcopy和Linux上的xclip。我经常使用这些工具。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 高级示例
run_some_command | copy
pasta > file_from_my_clipboard.txt

# 复制文件内容
copy < file.txt

# 从剪贴板打开文件路径
vim "$(pasta)"

# 解码剪贴板中的base64内容
pasta | base64 --decode

pastas将剪贴板的当前状态打印到stdout,然后每当剪贴板发生变化时,它都会打印新版本。我大约每周使用一次。

1
2
3
4
5
# 高级示例
pastas > everything_i_copied.txt

# 下载我复制到剪贴板的每个链接
pastas | wget -i -

cpwd将当前目录复制到剪贴板。基本上是pwd | copy。当我处于某个目录并想在另一个终端标签页中使用该目录时,我经常使用这个命令;我在一个标签页中复制它,在另一个标签页中cd到该目录。我大约每天使用一次。

文件管理

mkcd foo创建一个目录并进入其中。基本上是mkdir foo && cd foo。我经常使用这个命令——几乎每次创建目录时,我都想进入该目录。

tempe切换到临时目录。基本上是cd "$(mktemp -d)"。我经常使用这个命令跳入沙盒目录。它让我免于手动清理工作。几个常见示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 下载文件并解压
tempe
wget 'https://example.com/big_file.tar.xz'
tar -xf big_file.tar.xz
# ...对文件进行一些操作...

# 编写快速的一次性脚本来尝试某些东西
tempe
vim foo.py
python3 foo.py

trash a.txt b.png将a.txt和b.png移动到垃圾箱。支持macOS和Linux。我每天使用这个命令。我运行它的次数肯定比rm多,它让我免于意外删除文件。

mksh可以快速创建shell脚本。mksh foo.sh创建foo.sh,使用chmod u+x使其可执行,添加一些不错的Bash前缀,并用我的编辑器(我的是Vim)打开它。我每隔几天使用一次。这篇文章中的许多脚本都是用这个辅助工具创建的!

互联网

serveit在当前目录的localhost:8000上启动静态文件服务器。基本上是python3 -m http.server 8000,但会处理Python未安装的情况,回退到其他程序。我每周使用几次。如果你不是Web开发人员,可能不太有用。

getsong使用yt-dlp下载歌曲,通常来自YouTube或SoundCloud,以最高可用质量下载。例如,getsong https://www.youtube.com/watch?v=dQw4w9WgXcQ将该视频作为歌曲下载。我每周使用几次……通常用来获取视频游戏原声带……

getpod类似地使用yt-dlp为播客播放器下载内容。有很多视频我宁愿像播客一样听。我每月使用几次。

getsubs下载视频的英文字幕。(有一些技巧可以查找"官方"字幕,回退到自动生成的字幕。)有时我手动阅读字幕,有时我运行getsubs https://video.example/foo | ollama run llama3.2 "Summarize this",有时我只是想备份一个不想保存在电脑上的视频。我每隔几天使用一次。

wifi offwifi onwifi toggle对于控制系统WiFi很有用。当我遇到网络问题时,最常用的是wifi toggle。我大约每月使用一次。

url "$my_url"将URL解析为其组成部分。我大约每月使用一次来从URL中提取数据,通常是因为我不想点击恶意的跟踪链接。

1
2
3
4
5
6
7
8
9
url 'https://evil.example/track-user-link?url=https%3A%2F%2Furl-i-want-to-visit.example&track=06f8582a-91e6-4c9c-bf8e-516884584aba#cookie=123'
# original: https://evil.example/track-user-link?url=https%3A%2F%2Furl-i-want-to-visit.example&track=06f8582a-91e6-4c9c-bf8e-516884584aba#cookie=123
# protocol: https
# hostname: evil.example
# path: /track-user-link
# query: url=https%3A%2F%2Furl-i-want-to-visit.example&track=06f8582a-91e6-4c9c-bf8e-516884584aba
# - url https://url-i-want-to-visit.example
# - track 06f8582a-91e6-4c9c-bf8e-516884584aba
# hash: cookie=123

文本处理

line 10从stdin打印第10行。例如,cat some_big_file | line 10打印文件的第10行。这感觉像是应该内置的功能,就像headtail一样。我大约每月使用一次。

scratch打开一个临时的Vim缓冲区。基本上是$EDITOR $(mktemp)的别名。我大约每天使用一次来进行快速文本处理任务,或者记下一些一次性笔记。

straightquote将"智能引号"转换为"直引号"(有时称为"哑引号")。我通常不太关心这些,但它们有时会潜入我正在处理的代码中。它还可以使文件大小变小,这偶尔很有用。我至少每周使用一次。

markdownquote在每行前添加>。我在Vim中经常使用它;我选择一个区域,然后运行:'<,'>!markdownquote来引用所选内容。我大约每周使用一次。

length foo返回3。(我可能应该只用wc -c。)

jsonformat从stdin获取JSON并将其漂亮地打印到stdout。我每年使用几次。

upperedlowered将字符串转换为大写和小写。例如,echo foo | uppered返回FOO。我大约每周使用一次。

nato bar返回Bravo Alfa Romeo。我最常在与客户服务交谈时需要读出长的字母数字字符串时使用这个命令,这在我一生中只发生过几次。但它有时很有用!

u+ 2025返回ñ,LATIN SMALL LETTER N WITH TILDE。快速查找Unicode字符串的方法。我不经常使用这个……可能大约每月一次。

snippets foo输出~/.config/evanhahn-snippets/foo的内容。我使用snippet arrow表示→,snippet recruiter表示对招聘人员的快速"不感兴趣"回复,snippet lorem打印"Lorem ipsum"块,以及其他一些。我可能每周使用一两个。

REPL启动器

受Ruby内置的irb REPL启发,我制作了:

  • iclj启动Clojure REPL
  • ijs启动Deno REPL(或当Deno缺失时启动Node REPL)
  • iphp启动PHP REPL
  • ipy启动Python REPL
  • isql启动SQLite shell(sqlite3 :memory:的别名)

日期和时间

hoy以ISO格式打印当前日期,如2020-04-20。我经常使用这个命令,因为我喜欢用当前日期作为文件前缀。

timer 10m启动一个10分钟的计时器,然后(1)播放可听见的铃声(2)发送操作系统通知(参见下面的notify)。我经常使用bb timer 5m在后台启动一个5分钟的计时器(参见下面的bb)。我几乎每天都使用这个命令,作为跟踪时间的有用方式。

rn使用datecal打印当前时间和日期。我可能每周使用一次。它打印类似这样的内容:

1
2
3
4
5
6
7
8
9
4:20PM on Wednesday, October 22, 2025

   September 2025
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

音频、视频和图片

ocr my_image.png从图像中提取文本并打印到stdout。不幸的是,它只在macOS上工作,但我想修复这个问题。(我写了一篇关于这个脚本的文章。)

boop(别名,不是shell脚本)如果前一个命令成功则发出快乐的声音,否则发出悲伤的声音。我这样做:run_the_tests ; boop,它会通过声音告诉我测试是否成功。对于长时间运行的命令也很有帮助,因为当它们完成时你会得到一个小警报。我经常使用这个命令。

sfx foo基本上只是播放~/.config/evanhahn-sfx/foo.ogg。在上面提到的booptimer中使用。

tunes使用mpv播放文件中的音频。我经常使用这个命令,运行tunes --shuffle ~/music

pix使用mpv显示图片。我每周使用几次来看照片。

radio是我最喜欢的一些网络电台的小包装。radio lofiradio salsa是我最喜欢的两个。我每月使用几次。

speak从stdin读取,移除所有Markdown格式,并将其管道传输到文本转语音系统(macOS上的say和Linux上的espeak-ng)。当我不能大声校对时,我喜欢使用文本转语音。我每月使用几次。

shrinkvid是一个ffmpeg包装器,可以稍微压缩视频。我大约每月使用一次。

removeexif从JPEG中移除EXIF数据。我不太使用这个,部分原因是它不能从其他文件格式(如PNG)中移除EXIF数据……但我保留它,因为我希望有一天扩展它。

tuivid是我几乎从不使用的一个,但你可以用它来在终端中观看视频。它被诅咒了,我喜欢它,即使我从不使用它。

进程管理

each是我对xargsfind ... -exec的答案,我觉得这些很难使用。例如,ls | each 'du -h {}'对目录中的每个文件运行du -h。我不经常使用这个,但我总是搞乱xargs,所以这是一个不错的替代品。

running foo类似于ps aux | grep foo,但(对我来说)更容易阅读——只有PID(以紫色高亮显示)和命令。

murder foomurder 1234kill的包装器,它发送kill -15 $PID,等待一会儿,然后发送kill -2,等待并发送kill -1,等待,最后发送kill -9。如果我想停止一个程序,我想在变得更激进之前先礼貌地请求它。我每月使用几次。

waitfor $PID等待PID退出后再继续。它还可以防止系统进入睡眠状态。我大约每月使用一次来做这样的事情:

1
2
3
4
5
# 我想在另一个进程完成后才开始某事
waitfor 1234 ; something_else

# 我启动了一个长时间运行的进程,想知道它何时完成
waitfor 1234 ; notify 'process 1234 is done'

bb my_command类似于my_command &,但它真的在后台运行它。你再也听不到那个程序的消息了。当你想启动一个你真正不关心的守护进程或长时间运行的进程时,它很有用。我最常使用bb ollama servebb timer 5m。我大约每天使用一次。

prettypath打印$PATH,但用换行符分隔条目,这使得它更容易阅读。我很少使用这个——主要是在调试$PATH问题时,这很不寻常——但当我这样做时,我很高兴我有它。

tryna my_command运行my_command直到成功。trynafail my_command运行my_command直到失败。我不太使用这个,但它对各种事情都很有用。tryna wget ...会不断尝试下载某些东西。trynafail npm test会在我的测试开始失败时停止。

快速参考

emoji是我的表情符号查找助手。例如,emoji cool打印以下内容:

1
2
3
4
5
😛
😒
😎
🪭
🆒

httpstatus打印所有HTTP状态。httpstatus 204打印204 No Content。作为Web开发人员,我每月使用几次,而不是在线查找。

alphabet只打印英文字母表的大小写。我令人惊讶地经常使用这个(可能大约每月一次)。它实际上只是打印这个:

1
2
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ

系统管理

theme 0将我的整个系统更改为深色模式。theme 1将其更改为浅色模式。它不仅更改操作系统主题——还更改我的Vim、Tmux和终端主题。我至少每天使用一次。

sleepybear使我的系统进入睡眠状态,并在macOS和Linux上工作。我每周使用几次。

ds-destroy递归删除目录中的所有.DS_Store文件。我讨厌macOS用这些文件弄乱目录!我不经常使用这个,但当我需要时,我很高兴我有它。

杂项

catbin foo基本上是cat "$(which foo)"。用于查看路径中文件的源代码(例如,在撰写这篇文章时使用了它!)。我每月使用几次。

notify发送操作系统通知。它在我其他几个脚本中使用(见上文)。我大约每月做一次这样的事情:

1
run_some_long_running_process ; notify 'all done'

uuid打印v4 UUID。我大约每月使用一次。

你的脚本呢?

这些只是我经常使用的脚本。我希望其中一些对你有用!

如果你喜欢这篇文章,你可能喜欢"Why ‘alias’ is my last resort for aliases"和"A decade of dotfiles"。

哦,如果你有任何你认为我会喜欢的脚本,请联系我。

关于我

联系 项目 指南 博客 RSS 新闻通讯 Mastodon

除非另有说明,内容根据知识共享署名-非商业性使用许可协议授权,代码根据Unlicense授权。

徽标由Lulu Tang设计。 个人资料照片由Ali Boschert-Downs拍摄。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计