闲扯:CLI和GUI易用性的反直觉
挺久没写了,感觉是得写点啥,不然这网站感觉实在是有点摆设,上一篇文章尼玛20天前。而且我最开始的目标我明明记得我是想多增加和自己对话的次数,减少和ai扯淡的结果怎么越走越偏了。虽然说前段时间被期末周折磨的够呛也确实没啥东西好写,有些东西都已经放到“瞬间”板块了,不过cli和gui这个话题确实思考挺久了,自从开始入门Ubuntu开始就有这样的感觉。写下来吧
实际上促使我开始写这篇文章的原因是什么呢,其实硬要说有点凡尔赛。这段时间不是一直小学期在做实验吗,包括实际上之前的一些课程实验我也是用WSL2 + Ubuntu 24.04这个环境做的,一方面是实在是喜欢CLI的操作逻辑即便上手门槛是真的很高,另一方面是……比较喜欢打字。吧。不过按下这个不谈,前几天的YOLOv10实验,在自己的电脑上做。当时在训练的时候我对比别的同学,一些人在为环境变量等等配置焦头烂额,一些人在被莫名其妙的bug搞得满头雾水,一些人在苦苦等待训练结果,我已经在对着屏幕上的训练进度条优雅地喝茶耍手机了。我使用的是Kaggle上找到的一个交通标牌数据集,虽然数据集本身的图像质量不怎么样,但是训练速度该说不说是真的快。使用的命令举个例子
yolo detect train data=/home/astralcynsm/Files/Python/yolov10/ultralytics/cfg/datasets/traffic_signs_kaggle.yaml model=ultralytics/weights/yolov10s.pt epochs=50 imgsz=640 batch=8 workers=4 name=traffic_signs_run patience=50
yolo detect predict model=/home/astralcynsm/Files/Python/yolov10/runs/detect/traffic_signs_run3/weights/best.pt source=/home/astralcynsm/Files/Python/yolov10/kaggleDataset/traffic-sign-to-test.mp4
这个不谈。epoch=50的情况下,我使用这个大约含有900张交通标牌的数据集训练模型,在epoch=50轮的情况下,速度达到了7.7it/s平均。考虑到是游戏笔记本而且还是WSL2这种I/O相对受限的,这个速度相当不错了。然而我看别人的时候,他们的训练速度是远低于这个水平的,排查过pytorch等版本不匹配之后,这让我开始思考,CLI和GUI之间反直觉的易用性。
叠甲
首先叠个甲:本人写这篇完全就是瞎扯淡,不要当真,没有任何CLI比GUI高贵的意思,每个人有每个人自己的喜好,想用啥就用啥,GUI用户不必因为CLI可能的Nerd属性和不直观就去鄙夷,CLI用户也不能因为GUI的简单易用就去贬低,反智和精英主义都是要避免的趋向。好好说话.jpg
我们通常如何理解易用性?——GUI
GUI的设计核心就是:所见即所得(What you see is what you get),它所强调的是(或者说配合的是)人类五感中最为直观的那一个——视觉。点击、拖拽、右键菜单,一切都摆在眼前。GUI的原文是什么,Graphical User Interface,Graphical,图形化的。那么当然,显而易见的,GUI就被打上了直观、易用的标签,它相当符合人的直觉,降低了电脑的使用门槛。
我们当然无法否认GUI是直观的这个事实,对于绝大多数人来说,它开箱即用,哪里不会点哪里的操作逻辑的确也就等同于易用。然而,GUI的局限性也很明显:这是一种被动性的交互。比如一名厨师把他做好的所有拿手好菜都放在你面前,你是在选择没错,但是你能做的也仅限于选择,这是一种被动型的交互。系统为你展示,你“应该”做什么,系统只要等待你的选择指令就可以了,别的什么都不用做,你只需识别和选择。它的优点很明显,认知负荷低,非常符合也非常依赖人类的直觉和模式识别,它不包含,或者说很少包含“理解的成分”。因为你知道的是你“做了什么”,不是你“为什么”这么做。你和系统一起完成了任务,但是你不知道你是怎么完成的。你学会了点这里,但是并不知道点这里之后发生了什么,为什么要点这里。
GUI的局限大约有:效率上限低,很难把一些任务,尤其是重复性的任务给自动化。而且核心基本来说,是不透明的(除非有后台追踪器之类的东西但是实际上效果也有限),你不能或者很难知道点击之后发生了什么,无法定制组合深层逻辑。以及最重要的,用户只是“User”,而不是“Creator”。
当然,这样说实际上很大程度上是基于Windows的GUI,Linux的大部分发行版本和MacOS当然也有自己的GUI界面,也各自有各自的优点和局限,但是我觉得上述所说的这些GUI的总体特征是通用的,并不会因为内核的改变而改变,因为在GUI用户做的永远只是:点击。
易用性的另一面——CLI
对于大部分人来说,CLI那个黑不拉几的界面和一大堆令人望而生畏的字符,实在是让人有些难以接受——这b东西是不是那种天天把自己关在房间里面对着屏幕的Nerd才会用的?CLI的这种非直观的、复杂的界面,也就自然而然的成为了GUI的反面例子。很正常,CLI本来就不以直观而见长。相对较高的入门门槛首先筛掉了一批人,陡峭的学习曲线再次劝退了一批人,初看之下实际上非常不友好,需要大量的记忆和理解。
为什么我说CLI实际上深入下去才是易用的呢?实际上,CLI的核心中,用户所扮演的角色恰恰就与GUI相反:用户是创造者、思考者。仍然以上面的厨师为例子,如果说GUI是厨师把自己的拿手好菜全部摆在你的面前让你选择,那么CLI就是你吩咐厨师去做什么,而且你还能全程在旁边观看,去理解Ta是如何制作的。这是一种主动构建型的交互,系统等待你去告诉他“你知道要做什么”,这也促使用户去思考,为什么要这样做。这种初期的投入,实际上带来的是巨大的长期收益。
CLI虽然相当的复杂、不直观、高门槛、劝退,但是一旦开始精通CLI,那么它的优点反而是最符合计算机被设计出来的最原始的目的的:无与伦比的效率。一个操作,举个例子,我想要把一个文件夹里所有的.jpg文件都重命名为.png文件,在GUI里面大概需要一个个点击重命名然后重命名为.png文件,如果文件数量非常庞大的话,那么这就是一场灾难,甚至基本上是不可能人力完成的,到最后可能只能依赖专门的批量重命名工具,还不用提后续的导入文件、研究工具界面、寻找设置命名规则、预览然后执行,操作繁琐且每个工具的用法还大概率不通用,不统一。而在CLI里面,只需要这样一行命令:
for file in *.jpg; do mv "$file" "${file%.jpg}.png"; done
或者使用专门的rename工具:
rename 's/\.jpg$/.png/' *.jpg
解释一下那条指令:
for file in *.png是遍历所有jpg文件,mv是移动指令,在Linux内也用作重命名指令,${file%.jpg}.png这个不是正则,而是Shell内置的参数扩展功能,即去掉变量file末尾的.jpg,然后加上.png。整个过程几乎瞬间完成,无论有多少文件。
再举一个例子:倘若我们需要从一个高达几个G的access.log中找出访问量最高的10个ip地址。注意,这可是几个G的文本文档文件(.log算是一种.txt,可以直接重命名转换),如果用GUI的文本编辑器打开大概率会直接卡死崩溃,如果侥幸打开了,也得用Ctrl+F去一个个数ip地址,几千亿条,数到下辈子呢。用Excel?一导入直接爆炸,而且Excel的性能远比Notepad++等等的性能要差得多。而且Excel有行数限制。我们来看CLI:
cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10
这就是管道(pipe,|)的魅力:cat access.log,读取日志文件的全部内容并且扔到管道里面;awk '{print $1}'用来接收管道传来的内容并且打印每一行的第一列(假设是IP地址),然后再把结果扔到管道里;sort排序;uniq -c统计每个IP连续出现的次数并在前面加上计数值,再把结果扔到管道里;sort -nr,-n表示按数值排序,-r表示降序;head -n 10,只输出管道传来的内容前十行。行云流水,瞬间解决问题(因为一行一行流式处理数据)
再比如,想把当前文件夹的内容通过网页分享给局域网的同事看。如果是GUI,那估计得搞一两个小时:去网上搜索Windows Web Server,下载一个软件包比如XAMPP或者WAMP等,安装,启动Apache服务,找到htdocs在哪,把文件复制或者链接到那个目录,还不考虑可能出现的系统兼容性bug等等,如果不懂技术或者到最后实在不行只能干脆放弃。我们来看机器队……哦不是,人工队的表现:
python -m http.server 8000
搞定。只需要访你的ip:8000 (本地访问是localhost:8000)就能访问所有的文件目录了,如图:
CLI的效率在这些例子中基本是体现的淋漓尽致。并且,以Ubuntu为例,Unix/Linux系统的“一切皆文件”的思路让深度定制成为了可能,用户才是真正意义上的系统的主人。它强迫用户将目标分解,用逻辑构建解决方案,这本身就是深度学习的一个过程。
所以到底怎么?
直观是表面的,内核是深层的。
实际上我在上面已经说的很清楚了,反应式和构建式、被动和主动的区别。
GUI的优势非常明显:给你一本菜谱,跟着做吧。3个番茄,切块,2个鸡蛋,加盐5g,搅匀,热锅,倒油10ml,油温快要沸腾的时候倒入鸡蛋……只要照做,你几乎总能做出一道“还不错”的番茄炒蛋。核心问题是:你只是在复制,而不是在理解。为什么是3个番茄2个鸡蛋?为什么盐5g不是10g、2g或者不放?为什么油要快沸腾的时候再倒进去?我想做的更酸一点怎么办?如果我只有平底锅怎么办?菜谱没说,你也不知道。你是被菜谱(界面)牵着鼻子走的人,你是执行者,而不是创作者。你学会了做番茄炒蛋,你也吃上了番茄炒蛋,但是你没学会做饭。俗称,授人以鱼。这就是GUI的直观:它给你一个确定的路径,让你被动的跟随,从而免去了思考和理解的“痛苦”和花费精力。
现在想象,当你开始用CLI的时候,你不是拿着菜谱而是去学习烹饪的底层原理。美拉德反应,知道高温能让肉类产生诱人的香气和令人食欲大增的色泽;乳化作用,知道油和水如何通过蛋黄这样的乳化剂结合成酱汁;酸碱平衡,一点醋或者柠檬汁可以解腻提鲜。用户所掌握的是一个个基本的化学反应,也就是基础命令,grep, sed, awk,以及如何将他们组合起来。这无疑是困难的,需要记忆、理解抽象的原理并且不断实践,这也就是所说的高门槛和陡峭的学习曲线。但是回报是什么,你获得了真正的创造自由。你知道你想做什么,你知道你想做的背后的为什么。想让番茄鸡蛋的番茄味更浓?番茄膏,因为你知道风味浓缩的原理;想让鸡蛋更嫩滑甚至做出滑蛋的那种效果?你得会控制油温和翻炒时间,因为你知道有“蛋白质变性“这么个东西。这就是CLI的内核,它是严苛的老师,强迫你去理解事物的本质,让你掌握构建和创造的能力,从而在人机关系中占据绝对的主动。这就是授人以渔。
当我们把这个思考扩展到其他领域的时候,比如学习语言,学习数学理科等等,那一种内驱力才是最重要的。学钢琴,GUI模式让人只会照着五线谱弹其他人的歌,换一首歌拿到新的五线谱,无法即兴,也无法创作;CLI模式让人学习乐理、和弦构成、音阶。过程枯燥,但最终可以在任何调式上自由即兴,甚至创造出自己的旋律。打游戏,GUI模式让人跟着任务指引,哪里亮了点哪里,通关了,但感觉只不过是看了一场电影;CLI模式,研究游戏机制,理解数值系统,开发新的战术和玩法,享受探索和创造的乐趣。
回到最初:易用的目的是什么?
就像我在叠甲部分说的,各自有各自的好,每个人对于计算机对于电脑的需求并不一样,尤其是现在手机的大量普及,绝大多数人对GUI都非常熟悉。所以当我们讨论易用性的时候,我们必须先问一个问题:易用的目的是什么?为什么要易用?
如果目的是降低门槛,快速完成一个预设任务,那么 GUI 的“直观”是无敌的。但如果目的是提升效率上限,赋予创造的自由,并促进深度的学习和理解,那么 CLI 的“内核驱动”才是真正的、属于创造者的“易用性”。选择 GUI,是选择了一条被精心铺设好的平坦小径。选择 CLI,则是选择给自己一套登山工具,去征服一座充满挑战与无限风光的山峰。作为开发者,作为注定要与复杂系统打一辈子交道的人,而选择的必然是后者。因为很多时候,开发真正的乐趣,不在于安逸地到达,而在于亲手构建通往顶峰的道路。
说了这么多煽情的有点尴尬其实我感觉我这篇确实是在扯淡没啥特别含金量的东西,cli用到最后的人都懂,选择使用cli的人也懂,我只不过是把大家知道但可能没意识到的东西写出来了而已