V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  kuanat  ›  全部回复第 1 页 / 共 14 页
回复总数  265
1  2  3  4  5  6  7  8  9  10 ... 14  
dmesg 里面找 checksum error ,大概是这么个字符串,因为我这好久没出过错记得不是很清楚了。
6 小时 1 分钟前
回复了 yadam 创建的主题 Linux 分享一个 Linux 下的改键工具
我大致看了一下你的实现,讲道理你是个狠人啊……你不仅给 libevdev 做了 binding ,还内嵌了 quickjs 用来做配置自定义。因为我经常给自己的设备做固件写驱动,所以改键这部分还算比较熟悉,随便说一点想法。

1.
通过 uinput 虚拟输入设备,拦截物理设备事件(独占),映射完成后通过虚拟设备输出事件,这是唯一正确的做法。另一个我认为哲学上不那么正确的做法是,原物理设备不管,只重新映射事件。更准确的说法是这是处理两种不同需求的做法,前者的重点在于映射,后者的应用场景是脚本化、自动化,比如 AHK 这种,两者有重合的地方,但实际上是两种不同的设计方向。

2.
在这个“正确”的设计下,需要处理很多 corner cases ,我随便举一个类似方案很容易踩的坑:很多 gui 应用响应 alt 呼出菜单,假如有个改键逻辑是 alt+h 映射为 left ,当用户按下 alt 的时候,需要原样输出 alt 按下,同时设置 modifier ,之后按下 h ,此时以完全拦截,然后重新映射的视角来看,应该先释放 alt ,然后插入 left 。这时就会触发 alt 按下又释放的事件,就会被 gui 应用响应到。同时用户也没有办法再输入 alt+j 这个组合,这就给如何设计配置文件语法带来了挑战。

3.
配置文件用 js 这样的动态语言是一个可选的方向,但我不确定是不是个好的做法,比较直观的缺陷就是可读性和 debug 。以我对现有的各个实现的观察来看,应用提供 sane defaults 是非常重要,它可以极大简化配置文件的编写。特别是当你想实现类似 qmk layer 之类的功能的时候,全拦截重映射实际上要求每个按键都是重映射过的,配置文件如果要把所有逻辑都写一遍体验会不太好。

4.
获得当前活动窗口的名字是个看起来简单实际上复杂的事情,首先底层是 xorg 还是 wayland 要区分一次,xorg 稍微好解决一点,wayland 要做全兼容,大概主流的 mutter/kwin/wlroots 都要兼顾。各个实现对于 foreign-toplevel-manager 这个协议的态度差别很大。要么对 gnome 用 dbus ,对 kde 用 script api 一个一个适配,要么等各家支持相关协议。

5.
ctrl+c/v/x 映射到 ctrl+insert/shift+insert/shift+delete 是一个思路,但不是唯一的思路,比如你可以直接 super+c/v/x 映射到 XF86 的 copy/paste/cut ,更接近 mac 的逻辑。这方面 sway 这样的 wm 比起 gnome 这样的 de 要容易。另外 linux 的 clipboard 目前也是 wayland 协议的一部分,除此之外还有 primary selection 能用,可以发挥想象力。

6.
在这种系统调用层面上,go/rust 或者其他语言都差不多,只有不是 c 都会有 ffi 的问题。我只是单纯觉得,binding 都写了,不如直接写 c 了。另外不用 c 的话 IPC 带来的延迟会比较明显。




PS

下面写给对改键这个事情感兴趣的人看的。

首先明确几个概念 scancode/keycode/keysym ,scancode 是设备产生的硬件信号,经过内核 udev/evdev 之后转化为 keycode ,keycode 由内核空间传递到用户空间后,由桌面/窗口管理根据键盘 layout 转换为 keysym ,也就是应用程序获得的输入。

现在能够接触到的键盘类设备,只要不想专门做驱动,都会按照 linux headers 头文件( input-event-codes.h )定义的 keycode 去做,不然就是给自己找麻烦。当然像笔记本、游戏设备就需要自定义使用头文件里没有的 scancode/keycode 映射了。

以当前的 linux 生态来说,整个按键输入流程是这样的,硬件产生 scancode ,在内核空间经过 udev/evdev 处理映射为 keycode ,通过 /dev/input/eventX 暴露给用户空间。用户空间有 xorg/wayland 两个大的框架,对应的实现分别是 xorg-input-evdev 和 libinput ,注意前者虽然名字有 evdev 但实际上是用户空间的,意思是它利用 evdev 机制,此二者都是操作内核暴露的 /dev/input/eventX 接口,然后根据环境 locale/layout ,将 keycode 转换为 keysym 。由于目前 xorg 的实现也都过渡到 xf86-input-libinput 上面了,所以可以认为,用户空间就是 libinput 。此阶段之后,上层的桌面/窗口管理器可以获得特定的 keysym ,进一步传递给活动窗口应用。



综合上面的背景信息,可以说理论上有三个,但实践中只有两个可以做改键的位置。第一个是在内核空间通过 udev 规则改写 scancode 和 keycode 的映射,说它没有实践意义是因为这是设备厂家要做的事情。剩下两个有实践意义的,一个是 keycode 转 keysym 的阶段,另一个是 keysym 传递给应用窗口的阶段。

如果继续观察市面上已有的各种改键工具,会发现在 keycode 转 keysym 的阶段完成映射的方式,传统基于 xorg-input-evdev 的实现都只能支持 xorg ,而基于 libinput 的可以同时支持 xorg/wayland 。

至于为什么 keysym 传递给应用窗口这个实现也会存在,原因很简单,用户有针对特定应用改键的需求,而这个需求是前一种方式不能独立完成的。

所以现在改键就剩一种方式了,就是虚拟 uinput ,然后拦截物理设备事件做映射。区别就是要不要识别当前应用,以及如何识别。至于在 keysym 传递过程做映射,只有纯 wm 能实现,一般 de 是不开放这个自定义的。
64 天前
回复了 cosmain 创建的主题 程序员 关于自动升级和更新
部署和配置更新可以考虑 ansible ,中心式管理没有更简单的了,有 ssh 就行,没有性能需求。

ip 变动的话一般要靠设备主动汇报,一般负责心跳的模块顺便就做了。我这里之前用的方案是 ansible inventory 是通过外部接口调取的。
再补充一点,bios 里的选项位置是固定的,所以并不需要 OCR 之类的手段。多数时间只需要判断对应位置的选项是不是有高亮或者反色即可,即只需要判断当前光标是否选中了目标。
我给两个思路,OP 的判断是没问题的,常规自动化处理不了这种视频流内的信息。

1.
如果设备 bmc 比较新,我记得好几年前多数 bmc 都支持 redfish 协议了,那么你在 bios 里面要测试的项目可能多数可以直接走 bmc 的 redfish api 接口来实现。

2.
如果设备 bmc 比较老,那就通过 web 页面先抓一下输出的视频流,这个大概率是类似固定摄像机那种 mjpeg 流,本质上就是固定间隔的截图。这样可以省去在 web 界面上截图的逻辑。
然后就是逆向一下 web 界面发送按键序列的接口,用来做控制。这里需要注意的是,大概率还是要通过截图来判断状态,因为 bmc 那边接收到按键请求,但 bmc 把按键请求传递给主机这个环节不一定能 100% 正确响应。
再之后就是自动化的事情了。
73 天前
回复了 gtheone1 创建的主题 Android 小区门禁是 ID 卡,手机不能模拟吗
物理层面 ID 卡因为频率标准不一样,是没有办法模拟的。

某些情况下,可以用 IC 卡第一个扇区直接写 ID 卡号码,Big/Little Endian 可以都试一下。

原理是这些门禁设备硬件上是双频率的,也就是同时有 ID/IC 支持,软件写得不好,会把 IC 读取的结果当作 ID 序列号来判定。虽然比较少见,但我确实见过,当时我觉得匪夷所思,验证过之后才发现设备是双频率的。
@iv8d #105

JSX 是对 JS 语法的扩展,所以不是在 JS 里面写 HTML ,JSX 还是在写 JS ,只是这个 JS 扩展出来的语法部分非常像 HTML 。

JSX 里面像 HTML 的部分实际上就是在执行 JS ,并不是生成 HTML 代码,而是调用 DOM API 来达到和 HTML 代码一样效果。

所以最初在 JSX 里面要写 className ,因为这是 DOM API ,而不是直接用 HTML class 属性。
80 天前
回复了 lbbdefy 创建的主题 Linux 求助 ubuntu24.04 怎么创建虚拟屏幕当副屏幕
如果用 sway/hyprland 可以参考我这个帖子 https://v2ex.com/t/1046504

你上面的报错估计是因为你用的不是 sway/wlroots 。

Gnome/mutter 实现了一个 XDP 就是基于虚拟桌面的:

gsettings set org.gnome.desktop.remote-desktop.rdp screen-share-mode

我很久都不用 gnome 了,你需要搜一下上面这个配置项找下 gnome 的文档。
作为吃瓜群众我不理解的是 reactjs 的作者竟然认为,在控制流中使用嵌套三元操作是合理且应当大力推广的。
@wzy44944 #14

golang, 开发效率低执行效率高的语言? https://v2ex.com/t/1101972
Serverless 的优点是在 free tier 也就是用量很少的情况下省钱。再就是独立模块开发比较快。

我司之前有个图像分析的工作流尝试通过 cf ,即使是 paid plan 可用性也不是太好,如果换算成 sla 大概在 99.5% 左右吧,队列中的任务经常三五分钟的重试。

不过瑕不掩瑜,特别是随着 cf 支持 js 之外的语言,我个人很多自动化项目都上了 cf 。我尝试过好几个 serverless 平台,cf 还是更懂开发者的。
83 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
@lesismal #11

你说得非常对,我想了一下,还是 goroutine 更重要一些。

如果拿 js 来做对比的话,很明显 js 努力的方向一直是用同步的方式写异步逻辑,经过了 promise 到 async/await 的迭代,但 go 这边就很符合直觉。

另外性能在绝大部分场景不那么重要,可读性、效率和性能之间找个平衡点更重要。现在不是单体应用硬怼 c10k 的时代了。
83 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
@pursuer #7

这个讨论有点偏题了,我想表达的是浏览器相对于整个软件开发领域占比是有限的,这个数据无法支撑你得出“除 c 和 rust 之外被 js 占据”这样的结论。

我把这个帖子发在 go 而不是程序员节点,目的也是真正讨论工程化和生产力的问题。隔壁帖子的争论 xx 语言的 yy 不好,是建立在真的要把 xx 语言用在所有场景这样一个隐含前提下的。然而现实的人类并不会拿一把锤子就把万物当作钉子。

所以我不认为某种语言一统天下是个好事,这不符合我的技术哲学认知。
83 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
@tonyjia87 #6

对于编程语言来说,资本介入是好事。放在 1990 年可能还好,放到 2025 ,没有靠山的编程语言是没有生命力的。
83 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
@ninjashixuan #2

这里可能涉及到编程语言的设计哲学,即要在多大程度上暴露或者封装操作系统的抽象。

在 go 看来,内核 fd 是没有抽象过的 Reader Writer Closer 有用的,这种用接口的实现方式是对“万物皆文件”非常好的诠释。

同理,socket 相关的抽象也是一样。我个人认为这些都是有意的设计,最初就把跨平台作为目标之一,官方库就对如何封装如何抽象,实现哪些功能做了规划。

所以很多人说 go 的设计定位是 better c ,但我认为这不是重点,语言层面做个 better c 不难,其他语言一样做得很好。像 c 一样把操作系统底层完全暴露出来是没用的,go 优于 c 同时抢占了部分 c 的市场的原因是它解决了 c 工程化的很多问题。
83 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
@pursuer #1

编译速度说的是和编译类型的语言比,而且即使和 vm+jit 类型相比也是快的。

JS 的整个生态都建立浏览器之上,能力的边界取决于浏览器实现了多少对操作系统的封装。

如果一定要拿出数据作证的话,js 的份额一直就是在浏览器这个笼子里,别的进不来它也出不去。
关于 Go 日志的话题之前也有过几个帖子,可以参考一下,恰好我在那几个帖子里也有论述一些观点做法。

如何更好的打印日志 https://v2ex.com/t/1043663
golang 日志记录 https://v2ex.com/t/1038327
Golang 中的 Context 为什么只有上文没有下文?一般如何传递下文? https://v2ex.com/t/1012453


回到这个帖子的重点,关于“定位代码出错位置”这个需求,需要先明确调用栈的定义。除了代码层面的 call stack ,业务逻辑上 trace 也可以叫作调用栈。

从 OP 的描述来看,主要矛盾是业务流程上比较长,日志中间件的报错不足以定位特定模块代码层面 call stack 的问题。

我在上面引用的第一个帖子里提到过一些笼统的解决思路。

帖子里我提到的 debug/release 双版本具体实现是用 build tags 做一个开关,release 版本没有任何额外输出,debug 版本会输出 code path 的相关信息。或者理解成单元测试 coverage 的做法。这样不仅可以知道当前模块的输入、输出,也知道具体代码的分支路径。

这个做法给我节省了大量 debug 的时间,之前经常需要单步看执行逻辑,现在基本上看下分支流程就能大致定位问题了。并不是一定要通过反射或者什么方式获得出错的代码行才叫定位。
关于 Go 日志的话题之前也有过几个帖子,可以参考一下,恰好我在那几个帖子里也有论述一些观点做法。

如何更好的打印日志 https://v2ex.com/t/1043663
1  2  3  4  5  6  7  8  9  10 ... 14  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1001 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 26ms · UTC 19:52 · PVG 03:52 · LAX 12:52 · JFK 15:52
Developed with CodeLauncher
♥ Do have faith in what you're doing.