学习这件事不在乎有没有人教你,最重要的是在于你自己有没有觉悟和恒心。——法布尔

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
2
Sending 'file-or-folder' (X MB)
Code is: code-phrase

接收端则只需要:

1
croc code-phrase

这就是 croc 最有魅力的地方之一。它把“从这台机器把东西送到那台机器”这件事,压缩成了一个极其直观的流程:

  1. 发送
  2. 得到 code phrase
  3. 在另一台机器输入 code phrase
  4. 开始接收

这种感觉几乎像小时候递纸条时约定的暗号,只不过这里的暗号不只是识别身份,它还参与了安全机制本身。

那串 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
2
sudo port selfupdate
sudo port install croc

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
2
3
environment.systemPackages = [
pkgs.croc
];

Alpine Linux

1
2
apk add bash coreutils
wget -qO- https://getcroc.schollz.com | bash

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_PORTSCROC_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,这事大概率就能顺利发生。

而这种安心感,在工具世界里,往往比“功能很多”更难得。