croc
学习这件事不在乎有没有人教你,最重要的是在于你自己有没有觉悟和恒心。——法布尔
https://github.com/schollz/croc
croc:把“把这个文件发给另一台电脑”这件事,做得又简单又稳妥
文件传输这件事,奇怪得很。它明明是每个人都会遇到的日常动作,却总能在关键时刻变得异常麻烦:要么平台不通,要么要开端口,要么得先搭服务,要么刚传一半就断掉。更别提有时候你只想从一台电脑把文件发到另一台电脑,结果还得先思考网络环境、客户端兼容性和中间跳板。
croc 给这种局面的回应,非常干脆:Easily and securely send things from one computer to another。
它不是想重新定义文件传输,而是把一件原本就该足够简单的事,重新拉回简单本身。你给一台电脑一个发送动作,再把一串 code phrase 告诉另一台电脑,传输就开始了。没有一大堆花哨前置,也没有必须先建好的本地服务,这种朴素感正是 croc 最吸引人的地方。
项目地址:https://github.com/schollz/croc
它的目标很明确:任何两台电脑,都能简单而安全地互传东西
README 在 About 部分说得非常直接:croc 是一个允许任意两台电脑简单且安全地传输文件和文件夹的工具。
这里“任意两台电脑”这几个字很重要,因为它意味着 croc 并不是只面向理想的同网段场景,也不是只能在某个单一平台里自娱自乐。它想做的是一种尽可能通用的命令行传输方式。
README 甚至进一步强调,在作者认知范围内,croc 是唯一一个同时做到以下这些事情的 CLI 文件传输工具:
- 允许任意两台电脑传输数据,依靠 relay
- 提供端到端加密,使用 PAKE
- 支持跨平台传输,包括 Windows、Linux、Mac
- 支持多文件传输
- 支持中断续传
- 不需要本地服务器或端口转发
- IPv6 优先,并带 IPv4 回退
- 可以使用代理,比如 Tor
这组特性拼起来,几乎已经把 croc 的人格刻出来了:它不是一把只能在理想环境下用的小刀,而是一把考虑了现实网络复杂性、平台差异和传输连续性的工具刀。
最迷人的地方,是它的使用方式几乎像一句口令
README 在 Usage 部分给出的基础用法非常短。
发送端:
1 | croc send [file(s)-or-folder] |
执行后会出现类似这样的输出:
1 | Sending 'file-or-folder' (X MB) |
接收端则只需要:
1 | croc code-phrase |
这就是 croc 最有魅力的地方之一。它把“从这台机器把东西送到那台机器”这件事,压缩成了一个极其直观的流程:
- 发送
- 得到 code phrase
- 在另一台机器输入 code phrase
- 开始接收
这种感觉几乎像小时候递纸条时约定的暗号,只不过这里的暗号不只是识别身份,它还参与了安全机制本身。
那串 code phrase,不只是方便记忆的门牌号,也是安全协商的一部分
README 里特别说明:这个 code phrase 用于建立 PAKE,也就是 Password-authenticated key agreement。它会为发送方和接收方生成一个 secret key,用于传输过程。
这部分信息很关键,因为它说明 croc 的 code phrase 并不是单纯为了“让人类好输入”,而是和安全协商机制直接关联。换句话说,这串短语既是使用入口,也是加密协作的一部分。
因此,croc 给人的感觉不是“先想办法把文件送出去,再补点安全措施”,而是从传输动作一开始,就把安全纳入基础流程中。
它支持文件夹,也支持多个文件一起打包式传输
很多命令行工具在单文件场景里表现不错,一旦遇到多个文件、多个目录,事情就开始变复杂。croc 在这方面显得很实在。README 明确写到,它支持:
- 文件
- 文件夹
- 多文件同时发送
例如可以直接这样发:
1 | croc send [file1] [file2] [file3] [folder1] [folder2] |
这意味着你并不需要先手动压缩、再传、再解压,很多场景下直接把要发的目标列出来就行。对于日常使用来说,这个特性非常顺手。
断了也不怕,它支持恢复中断的传输
README 在 About 中列出的一个很重要的点是:Allows resuming transfers that are interrupted。
这个细节特别有现实感。因为真正烦人的不是“传不动”,而是“已经传了一半,结果断了,还得重来”。croc 把续传能力放进自己的核心特性里,本质上就是在对抗这种最让人沮丧的中途归零体验。
不需要本地服务器,也不需要端口转发,这种轻松感很值钱
很多跨机器传输工具真正的门槛,不是命令本身,而是配套的网络折腾。你可能得先启动本地服务、想办法暴露端口、处理 NAT、调整路由,最后文件都还没传,人已经开始怀疑人生。
croc 在 README 里明确把这一点作为核心卖点之一:No need for local server or port-forwarding。
这是一个很容易被低估的优点。因为一旦不用自己扛这些基础设施前置动作,整个体验就会从“部署一套传输方案”变回“发个文件”。
它很在意跨平台,不是在口头上,而是在安装路径上就写满了“到处都能用”
从 Install 部分就能看出,croc 非常认真地在铺设平台入口。它支持的安装方式覆盖面非常广。
通用命令行安装
1 | curl https://getcroc.schollz.com | bash |
macOS
Homebrew:
1 | brew install croc |
MacPorts:
1 | sudo port selfupdate |
Windows
Scoop:
1 | scoop install croc |
Chocolatey:
1 | choco install croc |
Winget:
1 | winget install schollz.croc |
Nix / NixOS
1 | nix-env -i croc |
以及在 configuration.nix 中加入:
1 | environment.systemPackages = [ |
Alpine Linux
1 | apk add bash coreutils |
Arch Linux
1 | pacman -S croc |
Fedora
1 | dnf install croc |
Gentoo
1 | emerge net-misc/croc |
Termux
1 | pkg install croc |
FreeBSD
1 | pkg install croc |
Conda / pixi
1 | pixi global install croc |
或:
1 | conda install --channel conda-forge croc |
Docker 方式
README 还给出了通过 Docker 在 Linux / macOS 上使用的方案,甚至提供了一段 shell function 一行式配置。
从源码构建
如果愿意自己构建,README 也给出:
1 | go install github.com/schollz/croc/v10@latest |
而且要求写得很明确:Go 1.22+。
这一长串安装方式并不只是“支持很多平台”那么简单,它传递出一个更本质的态度:croc 想尽量待在用户已经熟悉的环境里,而不是要求用户先迁移到某种特定生态才能用它。
Android 端也没有被忘掉
README 专门提到 Android 上有两个 F-Droid 应用可用:
crocgui—— 原始移植版,Go 实现,基础界面croc-app—— 原生 Kotlin / Jetpack Compose 客户端,现代化、移动优先界面
这部分信息很有意思,因为它说明 croc 的世界并不只属于桌面与服务器终端。哪怕 README 的主体是在讲 CLI 工具,它依然在试图照顾更广的设备使用场景。
它并不满足于基础发送,还在很多边角上做了很细的打磨
真正能体现 croc 成熟度的,其实是后面那一大段 Customizations & Options。这些内容让它从“能用”变成了“在各种现实场景里都更顺手”。
Linux 和 macOS 上的 secret 处理方式
README 提到,在 Linux 和 macOS 上,为了避免通过进程名泄露 secret,需要这样运行:
1 | CROC_SECRET=*** croc |
同时,对单用户系统,也可以通过下面命令永久启用默认行为:
1 | croc --classic |
这里连一个安全相关的小使用差异都被单独拿出来解释,说明项目对细节相当敏感。
自定义 code phrase
如果不想用自动生成的短语,可以自己指定,要求至少 6 个字符:
1 | croc send --code [code-phrase] [file(s)-or-folder] |
自动覆盖文件
接收时如果希望无需提示直接覆盖:
1 | croc --yes --overwrite <code> |
发送目录时排除某些文件夹
1 | croc send --exclude "node_modules,.venv" [folder] |
这类选项非常贴近日常开发使用。谁没在一个目录里夹着 node_modules 或虚拟环境呢?如果没有排除功能,命令行传输往往会变得不够优雅。
使用 stdin / stdout
发送时可以管道输入:
1 | cat [filename] | croc send |
接收时可以输出到 stdout:
1 | croc --yes [code-phrase] > out |
这部分很有 Unix 风格。croc 没有把自己做成孤岛,而是愿意进入 shell pipeline 的世界。
发送短文本
1 | croc send --text "hello world" |
这意味着它并不仅仅是大文件搬运工,有时候连一小段文本也可以顺手通过它发出去。
QR Code
如果要给移动设备接收,可以直接显示二维码:
1 | croc send --qr [file(s)-or-folder] |
这个功能很有温度。因为它显然是在为“电脑传手机”或者“手机辅助接收”这种场景做准备。
代理支持
通过 socks5 代理发送:
1 | croc --socks5 "127.0.0.1:9050" send SOMEFILE |
这和 README 前面提到的“Can use a proxy, like Tor”是呼应的。croc 并没有假设每个人都在最普通的网络环境里,它给了更复杂网络路径以明确入口。
更换加密曲线
1 | croc --curve p521 <codephrase> |
更换哈希算法
为了更快 hashing,可以使用 imohash:
1 | croc send --hash imohash SOMEFILE |
剪贴板控制
默认情况下,code phrase 会被复制到剪贴板。如果不希望这样:
1 | croc --disable-clipboard send [filename] |
如果希望复制完整命令,尤其对 Linux / macOS 上的 secret 模式有用:
1 | croc --extended-clipboard send [filename] |
这会复制出类似:
CROC_SECRET="code-phrase" croc
这样的完整命令。
Quiet 模式
如果在脚本和自动化里使用,希望完全静默:
1 | croc --quiet send [filename] |
这些零零碎碎的小功能,恰恰说明 croc 不是只把“传文件”做成一个单点 demo,而是在很多真实使用习惯上都下过功夫。
它还允许你自己跑 relay
虽然 croc 的一大优势就是不需要自己搭本地服务,但它也同时提供了 self-host relay 的能力。
运行自己的 relay:
1 | croc relay |
README 指出,默认使用 TCP 端口 9009-9013,也可以通过 --ports 自定义,例如:
1 | croc relay --ports 1111,1112 |
不过至少需要 2 个端口。
要使用自建 relay 发送文件:
1 | croc --relay "myrelay.example.com:9009" send [filename] |
Docker 跑 relay
README 还给出了 Docker 方式:
1 | docker run -d -p 9009-9013:9009-9013 -e CROC_PASS='YOURPASSWORD' docker.io/schollz/croc |
然后通过:
1 | croc --pass YOURPASSWORD --relay "myreal.example.com:9009" send [filename] |
来使用它。
如果要使用自定义端口,也可以设置 CROC_PORTS 或 CROC_PORT:
1 | docker run -d -p 9010-9011:9010-9011 -e CROC_PORTS='9010,9011' -e CROC_PASS='YOURPASSWORD' docker.io/schollz/croc |
这部分设计很有意思。croc 并没有在“易用性”和“可控性”之间二选一。默认情况下,它尽量简单;但如果你确实需要完全掌控中继路径,它也给出了明确入口。
它的强大之处,不在复杂,而在把复杂藏到了你不需要操心的地方
croc 给人的整体感觉,和很多喜欢炫技的网络工具不一样。它并不急着展示自己有多少高深概念,尽管 README 里其实已经提到了不少硬核能力:
- relay
- end-to-end encryption
- PAKE
- IPv6-first with IPv4 fallback
- resume interrupted transfers
- proxy support
- self-host relay
但它并没有把这些东西堆成门槛,而是尽量把它们包裹进一个很容易理解的操作模型里:send → code phrase → receive。
也就是说,复杂性并没有消失,它只是被小心地收纳在工具内部,避免把用户拖进不必要的配置深坑。
为什么 croc 会让人一用就很容易记住
因为它解决的是一种特别常见、又特别容易在关键时刻出错的需求:把东西从这台电脑送到那台电脑。
不是同步整套网盘,不是共享长期目录,不是搭协作平台,只是单纯、快速、安全地把东西送过去。这个需求太朴素了,朴素到很多工具反而不愿意只把它做好,而总喜欢顺手加上更大的叙事。croc 的可贵之处,就在于它没有把自己讲复杂。
它很清楚自己要做什么:
- 让任意两台电脑能传
- 让传输是加密的
- 让平台不是障碍
- 让中断不是终点
- 让复杂网络环境也有办法走通
- 让用户不用先学习一整套网络运维知识
于是你会发现,croc 最终带来的不是某种宏大的“下一代文件传输体验”,而是一种很踏实的安心感:
当你手上有东西要发,只要另一台机器能跑 croc,这事大概率就能顺利发生。
而这种安心感,在工具世界里,往往比“功能很多”更难得。
