可查询的可执行文件
我很高兴看到我的文章《你的可执行文件是一个SQLite数据库》引起了人们的共鸣。这是我思考了很久的一种格式,似乎这个想法与他人产生了共鸣。简要回顾一下:SELF,是一种程序格式,它是一个SQLite数据库。我们可以使用binfmt_misc来触发一个自定义解释器,该解释器映射段表中的行并跳转到入口点,从而将一整类二进制工具压缩为SQL。令我感到惊讶的是,这种文件格式作为SQLite数据库不断将一切简化为SQL。通过评论,自己和其他人很快就意识到了一个想法:如果可执行文件是一个数据库,而数据库是可以写入的东西,那么正在运行的程序可以利用它来存储其状态吗?🤔 是的!🤯 我们不仅可以将一个完整的发行版压缩为一个文件,还可以将每个应用程序的所有状态压缩为一个文件,从而消除对/var/,/tmp/,/home/或任何其他文件系统的需求。程序可以在其运行的同一个文件中存储其状态,并且可以以事务方式进行。self-httpd是一个完全满足这些条件的概念验证web服务器。它是一个从数据库执行的单文件程序。该文件包含程序、网站、路由和所有访客日志。所有状态都在与程序本身相同的SQLite文件中更新。# 我们的服务器是一个单文件,并且是一个SQLite数据库$ file server server: SQLite 3.x数据库,应用程序id 1397050438,...$ ./server --journal wal 8080 self-httpd: 从/srv/self/server服务3个路由self-httpd: 在http://0.0.0.0:8080上监听,4个工作进程$ curl -s localhost:8080 | head -1 <!doctype html> # 还没有人按下那个页面上的按钮$ sqlite3 server 'SELECT count(*) FROM presses' 0$ curl -s -X POST -d press localhost:8080/api/press {"presses":1,"button":"press"} # 应用程序数据在同一个数据库中$ sqlite3 server 'SELECT id, at, button FROM presses' 1|2026-08-25 03:11:28|press # 获取页面所需的GET请求也是如此$ sqlite3 server 'SELECT count(*) AS n, path FROM visits GROUP BY path' 1|/ 1|/api/press 这个web服务器在https://selfdb.exe.xyz上运行。1 1 如果网站无法正常工作,很抱歉。我在他们的最小套餐上部署了它。我为了留下记录而包括了网站的截图!它是一个文件,一个SQLite数据库,同时也是服务器。它是网站,它是程序,也是访客日志和状态。§ 一切都是我的恶魔缪斯我非常钦佩Justine Tunney的工作,她的早期艺术作品redbean:一个单文件的web服务器,作为一个真实便携式可执行文件,构建为一个自解压的ZIP档案,启发了这个想法。SELF在某种意义上不那么出色。它依赖于简单的工具来实现非常类似的东西,但我惊讶于有多少东西被压缩到一个单一的领域:SQL。而redbean需要包含一个归档格式(ZIP),数据库本身就是容器。redbean提供Lua钩子来操作响应,而在SELF中,相当于是处理程序表中的一行。INSERT INTO handlers VALUES ( '/api/busiest' , 'SELECT path, count(*) FROM visits GROUP BY path ORDER BY 2 DESC LIMIT 5' ); 如果redbean是一个真正可移植的可执行文件,那么这是一个真正可查询的可执行文件。它们的一个可以在任何地方运行,另一个你可以从中进行SELECT。§ 你只需要argv[0]进程如何访问自己?🤔 目前,你无法使用/proc/self/exe。2 2 有趣的是,VFS Linux维护者最近在内核中添加了对透明binfmt_misc的支持,这将使/proc/self/exe指向原始文件。我在这里写过。当binfmt_misc匹配时,内核根本不执行你的文件,它执行解释器,并将路径传递给它:self-exec将argv + 1传递给程序,因此程序的argv[0]就是可执行文件本身的路径。解释器在跳转到入口点之前还释放了它的SQLite连接,以便程序可以打开其自己的文件并查询它。int main ( int argc , char ** argv ) { sqlite3 * db ; /* 内核刚刚执行的文件 */ sqlite3_open ( argv [ 0 ], & db ); ... } 这非常不受限制且神奇。你可以读取自己的段表或旁边的新表。写入在调用之间持久化。✨ § self-httpd 作为我们示例的web服务器,有三个表:routes,visits和presses。我们将记录每个访客和每次按钮按下。 -- 内容,被添加到可执行文件中 -- 编译和链接后 CREATE TABLE routes ( path TEXT PRIMARY KEY , mime TEXT , body BLOB ); -- 网站收集的内容,在它运行时写回 -- 到可执行文件中 CREATE TABLE visits ( id INTEGER PRIMARY KEY , at TEXT , ua TEXT , path TEXT ); CREATE TABLE presses ( id INTEGER PRIMARY KEY , at TEXT , button TEXT ); 构建应用程序的过程感觉非常平常且熟悉。我们执行DDL以创建应用程序模式。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡