记录每天所学到的、想到的和遇到的:
发现了一个很适合用 Emacs eww 访问的电子书网站:
https://www.gutenberg.org/browse/scores/top
linux 下的 logger 命令
在 debug 一些没有 stdout,stderr 的脚本的时候,可以用 logger 写日志,可以用 journalctl 查看日志。
|
|
$ echo eb3ae38f27191aa5f3850dc9cad00492b88b72404f9da135698679268041c54a | fold -w2 | tac | tr -d “\n”
|
|
tac - concatenate and print files in reverse
fold - wrap each input line to fit in specified width
寻找一个能方便地完成 binary,hexadecimal, decimal 互相转换的办法?
我以前喜欢用 printf
来做 decimal 和 hexadecimal 之间的互相转换:
|
|
但是 printf 不能转换到 binary 格式。。。。。
所以用 python 吧,一行就能搞定:
|
|
vim 的 –clean 参数
我想用 vim 阅读一个超级大的日志文件,可以使用 vim 的 –clean 参数,来避免加载那些自定义的 vim 插件。
https://vimhelp.org/starting.txt.html#--clean
如何触发 PCIe 设备的重新发现
|
|
向这个文件写 1
,就能触发 PCIe 设备的重新发现。
Ref:
waitpid(2)
wait for a child process to stop or terminate
https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html
linux command: waitpid
|
|
发现一个好东西: fzf-git-checkout
https://polothy.github.io/post/2019-08-19-fzf-git-checkout/
Immutable vs Mutable Objects
https://medium.com/@katerinaCodes/immutable-vs-mutable-objects-d30ea96fb585
IN_NIX_SHELL
环境变量可以判断自己是否处于 nix-shell 当中
学习 NixOS
是的,我大概在一个星期之前的周末,安装了 NixOS。
我就只略微地了解了 NixOS 大致工作流程是怎样的,就直接上手安装了。
好在这个过程很顺利,然后我花了两天的时间去折腾 NixOS,学习它的配置方式,安装我日常需要的包,折腾 home-manager, 折腾 flake,nix-shell, overlay 等等,在两天的时间内,已经折腾到可以满足我日常使用需求的状态了。
关于 flake, nix-lang 的语法,配置文件的规则,overlay 等等我目前都没完全搞明白。
在这里贴一下我收集到的有帮助的链接:
tail 的 -F 控制参数
我正在用一个脚本做两件事情:1.删除当前项目目录下的 tmp 目录。2.在 tmp 目录下初始化并启动一个节点服务。
如果我用 tail -f ./tmp/data/logs/run.log
来查看日志的话,并不会继续查看删除 tmp 之后的新生成的 tmp 目录下的文件,而 tail -F
却允许我追踪重新创建的文件。
|
|
调整 Cargo jobs 数量
以前我并没有调整 Cargo jobs 的数量,当我 执行 cargo build 的时候,我的 12 个 CPU 全部全力工作,这会导致我的操作系统略卡,不能及时响应我的键盘/鼠标动作。
所以我专门留一个 CPU 给操作系统,其他的 11 个 CPU 全力工作,这样我的操作系统就不会卡了。
参见: https://doc.rust-lang.org/cargo/reference/config.html#buildjobs
用 strace 追踪一个多线程进程的时候,可以考虑 -f 参数
也可以用 -p 仅仅指定一个线程 ID, LWP(Light Weight Process)
一个正在增长的文件,统计它的行数增长速度。
我正在观察节点同步过程中的日志,日志文件是一个不断增长的文件,我想知道它的增长速度(也就是区块增长的速度),于是想了一下,linux
有一个 叫 pv
(pipe viewer
) 的命令能做的事情和我的需求很贴合,但是 pv
好像是用来统计 pipe
接收方的 byte
粒度的,而我要统计的是行数,man pv
看了下, pv
还有 -l
参数,完美的解决了我的需求:
|
|
这样就能实时看到节点同步速度了。
ps -eLF 的结果里 LWP 代表 Thread Id?
我今天想用 ps 命令知道一个进程在运行过程中,都有哪些线程在跑,于是用了ps -eLF
发现了 NLWP
和 LWP
列名, NLWP
是线程数, LWP
是线程 ID
。
LWP: Light Weight Process
https://www.thegeekstuff.com/2013/11/linux-process-and-threads/
Linux 下为给一个进程下面的所有线程都设置优先级
最近我正在为区块链节点的同步做 benchmark,同步过程中不仅有 IO 操作,也有 CPU 操作。我想看看同步耗时的瓶颈在于通过 p2p 拿到区块之后的 process_new_block() 动作,于是我就把节点的 p2p 相关部分给魔改注释掉,预先为 process_new_block() 准备好 headers 和 blocks,同时想着为节点进程设置最高优先级。
我一开始是这么做的:
|
|
后来我用 htop 工具看了下,这个进程下有很多个线程,但是只有 PID 和 PGID 相同的那个线程的优先级被改了,其他的线程的优先级还是默认的。
于是我这样做:
|
|
这样所有的线程的优先级都被改了成了最高优先级。
再看下 renice 命令的可用参数:
|
|
原来 docker run 的 -p 参数是用 docker-proxy 来完成 ports mapping 的
使用 qbus 来控制 kde compositor 的 suspend/resume
还记得当初选择 KDE plasma 来作为我的 wm 是因为它有非常漂亮的特效,但是用久了就对那些特效没感觉了。于是我就关闭 compositor 了。
因为我偶尔需要让某些特殊窗口拥有 transparent 的效果,所以我就不得不控制 compositor 的启用、关闭。
搜了一下,我可以使用 qdbus 来做这件事情
|
|
- 恢复 compositor:
qdbus org.kde.KWin /Compositor resume
- 暂停 compositor:
qdbus org.kde.KWin /Compositor suspend
Effective UserID, Real UserID, Saved UserID
- Real UserID:
The Real UserId is the UserID of its user who initiated the operation. It specifies which documents are accessible to this operation. It is the person who owns the operation.
- Effective UserID:
The Effective UserID is identical to the Real UserID, but it could be modified to permit a non-privileged person to use the documents that are typically accessible only to privileged users such as the root. It is used by the computing system to determine if you are allowed to do a particular task or not.
- Saved UserID:
The Saved UserID is a cast-off while a main task being performed contains high confidentiality. Most of the time, its root has to do work that requires less privilege. This can be accomplished by briefly transitioning to a non-privileged profile.
让 grep 保留 ps 第一行的列名
我平时这样用 ps 和 grep:
|
|
有时候我可能会改变 ps 的参数,同时我还想知道每一列都是什么意思,于是我想着怎么才能将 ps 输出结果的第一列保留下来。想了一下,我最后这样做:
|
|
看下效果:
|
|
执行结果符合预期。
Linux coreutils 里的 rmdir 命令
|
|
其实也可以用 find
:
|
|
How to remove all empty directories in a subtree?
Jetbrians IdeaVIM 的 Forward 和 Back 不工作了
nmap <C-i> :action Forward<CR>
nmap <C-o> :action Back<CR>
https://youtrack.jetbrains.com/issue/VIM-2225
google chrome 无法播放视频
今天发现 YouTube
无法播放视频了,于是很纳闷?难道我这几天新安装了什么插件吗?仔细一回想,没有啊。
然后我从命令行启动 Chrome
发现以下日志:
|
|
奇怪,看起来是音视频硬件加速出了问题。
从 vainfo
发现了诡异的地方:
|
|
有一行是 unknown profile
https://forum.manjaro.org/t/nvaapi-video-acceleration-on-google-chrome-stable-not-working/100109/3
从这个 issue
看到说需要安装 libva-vdpau-driver-chromium
?奇怪,以前我从来没安装过这个包啊。
|
|
安装 =libva-vdpau-driver-chromium= 完之后:
|
|
再次启动 chrome 又发现新的问题
[48720:48720:0513/172226.125496:ERROR:gl_utils.cc(319)] [.WebGL-0x3b600379bf00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels
奇怪?这次看起来是显卡的问题, GPU stall
了。
linux 的 faillock
今天感觉键盘上有很多灰尘,想擦一擦,于是先锁屏,然后用湿巾疯狂擦了几下键盘,擦完发现因不小心触碰了很多次解锁键,失败次数过多,得等 10 分钟后才能解锁。
于是了解到了: faillock
https://linux.die.net/man/8/faillock
只能以 root 身份从 tty 登录,然后
|
|
vim 中的 ysiw, 和 cs
|
|
ysiw]
surround a text object with ‘=’
https://github.com/tpope/vim-surround/issues/128
linux 下从进程的 pid 去寻找这个 pid 属于哪个 docker 容器
今天有同事发现公司一台服务器占用的资源较多,他从 =top= 拿到了 =pid= 。
于是搜了一下, =/proc/= 下面可以查看 =/proc/${pid}/cgroup= 来得到 =containerId=
|
|
今天学到了 xargs 的 –max-procs 参数
我负责公司以太坊节点的数据导出到 apache parquet
的工作,我为erigon
写的导出工具是单线程的,导出数据不仅会有磁盘的I/O
操作,也会有一些消耗CPU
的压缩操作。
以太坊节点所在的机器有16
个核,我以前是这样写并发导出脚本的:(为了突出重点,我做了精简)
|
|
这段代码的缺点是:在 ${parallelCount} -eq ${MAX_PROCESS}
为true
的时候,程序会一直等待,即使并发任务数量降为1
。这不是我能够容忍的。
于是我了解到了 xargs
的 --max-procs
-P max-procs, –max-procs=max-procs
Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; otherwise chances are that only one exec will be done. While xargs is running, you can send its process a SIGUSR1 signal to increase the number of commands to run simultaneously, or a SIGUSR2 to decrease the number. You cannot increase it above an implementation-defined limit (which is shown with –show-limits). You cannot decrease it below 1. xargs never terminates its commands; when asked to decrease, it merely waits for more than one existing command to terminate before starting another.
于是我将代码这样修改:
|
|
完美!这样cpu
就不会闲着了。
我想将我的私人文件不被 git track, 但又不方便加入到 .gitignore 里面
我在和他人合作开发一个项目的时候,会自己写很多私有的脚本,每次在 git add
的时候都要关心一下有没有把不该track
的东西给track
了,本来可以加入到 .gitignore
里, 但是我又不想把我的私人文件加入到 .gitignore
里。
搜了一下, 也可以加入到 .git/info/exclude
里, 这个文件不会被 git track.
https://git-scm.com/docs/gitignore
Linux umount 时遇到: target is busy
今天坐在我工位对面的同事尝试对存放以太坊节点数据的磁盘执行 umount
操作, 遇到了 target is busy
这个问题。我的直觉告诉我这应该是有个进程正在读写这块硬盘。所以 umount
才会失败。
于是立即学习一下 core/psmisc
包里面的fuser
命令,和 lsof
命令。
从man
手册可以查到:
fuser: fuser displays the PIDs of processes using the specified files or file systems.
fuser returns a non-zero return code if none of the specified files is accessed or in case of a fatal error. If at least one access has been found, fuser returns zero.
fuser
的ACCESS
列展示了相关进程的具体 access 信息
c current directory.
e executable being run.
f open file. f is omitted in default display mode.
F open file for writing. F is omitted in default display mode.
r root directory.
m mmap'ed file or shared library.
. Placeholder, omitted in default display mode.
fuser
有 -m
选项:
-m NAME, –mount NAME
NAME specifies a file on a mounted file system or a block device that is mounted. All processes accessing files on that file system are listed. If a directory is specified, it is automatically changed to NAME/ to use any file system that might be mounted on that direc‐
tory.
|
|
我注意到,即使我的zsh
离开了 外置硬盘所在的目录时, 这个硬盘依然被使用着,因为我用了 zsh 的一个 git status daemon 插件,这个插件估计会定时获取远程 git 仓库的状态。所以 fuser 展示了 gitstatusd-linux
后来我退出了 zsh shell
, gitstatusd-linux
才退出。
vim 使用 column 命令将若干列文本对齐
我的需求是这样的,想把这三列文本从上面的样子变成下面的样子:
|
|
只需进入 vim
的VISUAL
模式,选中那十几行,然后 :!column -t
即可。
将 Google NCR 设置为浏览器默认搜索引擎
我不喜欢 google 返回我和我位置信息相关的搜索结果,于是设置一下 Google NCR (No Current Region)
https://10wontips.blogspot.com/2018/07/always-search-google-in-english-by.html
我今天学到的 Linux 命令: disown
为了搞懂 disown
命令,必须得搞明白 linux
的 jobs
这个概念。
job
其实就是 shell
管理下的进程,每个 job
都有唯一的 job ID
, job
有 3 中状态: foreground
, background
(在命令末尾用了 & 符号), stopped
(按下 Ctrl-Z 会使得前台进程处于该状态)
与 job
相关的命令有这几个:
|
|
如果你其他以 cmd &
的方式让一个进程工作在后台,当你退出 shell
后,该进程就会挂掉,要么你用 nohup
来启动,或者考虑 disown
|
|
disown
可以让指定 job
从job table
中移除,这样 即使你退出 shell
, 后台进程也不会挂掉。
其中 -h
参数可以让 disown
在终端退出之后才生效。
可以做个实验:
- 从 shell 中以命令的形式启动 discord :
/usr/bin/discord --balabala
- Ctrl-Z 暂停 discord
- ps -eF | grep discord # 查看 discord 进程 的父进程是谁,应该是 shell 进程
- 执行 disown # 从 job table 中移除 discord 这个 job
- kill -CONT [discord 的 PID]
- ps -eF | grep discord # 查看 discord 进程 的父进程是谁,应该不是 shell 进程了,在我本机上是 systemd 进程
vim 用户必须了解的 的 motion 和 operation
awk 不定长句子的最后一个单词
|
|
NF 表示这行句子的字段数。
vmtouch: 一个可以分析/控制文件系统缓存的工具
我拥有很多 roamXXXX.org
文件, 还有一个超级大的 org-journal
文件,每当我第一次用emacs
打开这些大文件后,感受到明显的卡顿,我认为这明显的卡顿其中从磁盘冷加载文件贡献了 30% 的卡顿,然后就是解析大文件,格式化和 highlight 贡献了 70% 的卡顿。于是我想让电脑在第一次开机的时候,将这些预读一下,旁加载到page cache
里。最简单粗暴的方法,就是写个循环,把这些文件都 cat * > /dev/null
, 后来找到了更为优雅的工具: vmtouch
https://hoytech.com/vmtouch/
|
|
vmtouch 可以将文件 touch
进内存, 也可以将内存中的文件缓存 evict
出内存。
vmtouch 的用了这些系统调用:
|
|
scrcpy 控制安卓手机
我拥有一个安卓手机,没有 root,今天想通过 Linux 系统来控制手机,于是折腾了一下,找到了 scrcpy 这个包:
|
|
https://github.com/Genymobile/scrcpy
注意是scrcpy
不是scrapy
, scrapy
是 python 的一个爬虫框架,我们需要的是scrcpy
我本来可以通过 usb 数据线链接手机,然后开启 adb 调试模式的,但是嫌麻烦。找到了通过 wifi 链接手机 adb 调试的方案:
并且通过 adb 解锁手机锁屏。
https://stackoverflow.com/questions/29072501/how-to-unlock-android-phone-through-adb
这样就能愉快的操控手机了~
Linux 控制外接显示器的亮度
因为我最近把外接显示器放置的比较远,我目前在坐的位置是面对窗户并且面朝东。早上阳光非常刺眼,就得将显示器亮度调高点才合适,晚上又得吧显示器亮度调暗。我懒得伸手去操作显示器,所以从终端控制:
我用的 archlinux,需要这个包
|
|
然后 load i2c-dev module
|
|
现在 ddcutil 就可以使用了:
|
|
大功告成,以后我再也不用伸胳膊去够显示器后面的调节按钮了。
:-D
Wikiwand: Wikipedia Modernized, 一个可以让你的 wikipedia 页面更好看的 chrome 插件
https://chrome.google.com/webstore/detail/wikiwand-wikipedia-modern/emffkefkbkpkgpdeeooapgaicgmcbolj
使用 kdeconnect-cli 为手机分享文件或文字
因为懒得去动鼠标/触摸板来 操作 kdeconnect 的图形界面,所以研究了一下如何在终端里将文件分享给手机。
|
|
https://userbase.kde.org/KDE_Connect/Tutorials/Useful_commands
一个可以为远古时期的网页设置 syntax highlighting 的 firefox 插件:Enlight
https://addons.mozilla.org/en-US/firefox/addon/enlight/
zsh 快捷键相关的
其实很久以前就知道 bash/zsh 有很多移动鼠标的快捷键是从 emacs 那里移过来的。
今天我在 zsh 下工作时,巧合地触发了 M-x 键,它给我弹出了个 execute prompt
, 于是我研究一番,zsh 下的 M-x 竟然和 emacs 的 M-x 相通,都是用来execute-command
的
https://unix.stackexchange.com/questions/440159/regarding-altx-in-zsh-and-how-to-bind-altx-to-something-else
ssh forward 遇到 bind: Cannot assign requested address
我今天在执行ssh -N -L port1:address:port2 server
时遇到了这个问题:
https://www.electricmonk.nl/log/2014/09/24/ssh-port-forwarding-bind-cannot-assign-requested-address/
原来是 ssh 试图 bind ipv6 地址
指定 ssh -4 使用 ipv4 地址 即可。
用命令行将 html 导出为图片
- 用
google-chrome
|
|
List of Chromium Command Line Switches
https://developers.google.com/web/updates/2017/04/headless-chrome
https://dschnurr.medium.com/using-headless-chrome-as-an-automated-screenshot-tool-4b07dffba79a
- 用
wkhtmltoimage
|
|
Emacs 将 org-journal-entry 同步到 telegram channel 里
我使用 org-journal
来记录生活,但是 org-journal
是离线的,我创建了个 bot
来将单条 org-journal-entry
同步到 channel
里。
|
|
茴香豆的茴有几种写法之 VIM 有哪几种退出方式?
- :wq / ZZ / :x
- :q! / ZQ
日志里面第一列是 ip, 查询出现次数前 10 的 ip
|
|
grep pdf 文件
为 tmux 的 pane 名称设置不同的 emoji 后缀
生活要过的多姿多彩,同样的,我的终端也必须多姿多彩。于是我给 tmux
的panel
添加了随机的emoji
后缀
写一个shell
脚本,放进我喜欢的emoji
|
|
然后在tmux
里这样设置pane
的名称,:
|
|
大功告成!
direvent
GNU direvent - Summary [Puszcza]
OCR 应用: tesseract
有时候身边的同事在排查问题的时候,会从用户那里得到图片形式的hash
,为了debug
,我本可以手工将图片形式的哈希转化为文本形式的,可是我实在是嫌麻烦,于是玩了下这个从 2006 年开始由Google
maintain 的 OCR
工具: tesseract-ocr/tesseract
ArchLinux 下所需的包
|
|
第一个是主程序,其他的都是由Google
训练好的中文和英文模型库。
tesseract
的使用规则是这样的:
|
|
我的使用流程是: 从屏幕上截图,截图会自动保存到粘贴版,然后:
|
|
如果不加preserve_interword_spaces=1
的话,识别出的结果就会有烦人的空格。
结果很准确,甚至是同时有中文英文和符号的图片都能识别!
使用 sed 获取一个文件位于两个关键词之间的内容
比如:
> cat file.txt
first line :head
second line
third line
apple
forth line
...
tiger
last line
tail
|
|
goland 缺失的功能
我用goland
开发公司的项目,很喜欢goland
的rename usages of 变量/函数 A to 变量/函数 B
的功能,但是我却不能对 import 这么做, 要是想改变整个项目都某一个包的引用,不得不使用 sed
:
|
|
*nix 环境,快速生成大量随机的 leetcode 测试用例
当我在 leetcode
做了一道算法题后, 我会先在心里考虑一下输入的边界情况(或者非法输入),时间复杂度(要是数据里过大并且我的算法时间复杂度太差就会 Time Limit Exceed)。
所以我要么手动在 test cases
里手写测试用例, 要么用 linux
下这么几个有用的命令随机生成大量的测试用例:
|
|
用这三个简单的工具, 一般就能生成我想要的测试数据了。
比如我想生成一个数组, 数组的每个元素都是数字,整个数组要是 unsorted:
|
|
要是想要超大的数据量, 我一般会写到 /tmp/
里,再配合 xclip
将内容读进到 粘贴板, 最终粘贴到网页里去
https://leetcode.com/problems/combination-sum/solution/
|
|
我喜欢用 printf
配合这些工具输出我想要的格式:
|
|
心中的疑惑
- 在终端里快速生成大量随机数的最佳实践是什么?
gorm 链接 MySQL 处理 Error 1390 错误
我在公司负责的项目中使用了 gorm, 有一次 批量插入数据时遇到了 1390 :too many placeholders
所以我不得不减少数据量,为了解决问题将代码这样修改:
|
|