This page looks best with JavaScript enabled

Today I Learned/Thought/Found

 ·  ☕ 7 min read
    🏷️
  • #TIL

记录每天所学到的、想到的和遇到的:

将 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 相关的命令有这几个:

1
2
3
jobs # 列出 jobs 列表
bg %n # 让该 job 在后台工作
fg %n # 让该 job 在前台工作

如果你其他以 cmd & 的方式让一个进程工作在后台,当你退出 shell 后,该进程就会挂掉,要么你用 nohup 来启动,或者考虑 disown

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ help disown
disown: disown [-h] [-ar] [jobspec ... | pid ...]
    Remove jobs from current shell.

    Removes each JOBSPEC argument from the table of active jobs.  Without
    any JOBSPECs, the shell uses its notion of the current job.

    Options:
      -a        remove all jobs if JOBSPEC is not supplied
      -h        mark each JOBSPEC so that SIGHUP is not sent to the job if the
                shell receives a SIGHUP
      -r        remove only running jobs

    Exit Status:
    Returns success unless an invalid option or JOBSPEC is given.

disown 可以让指定 job 从job table 中移除,这样 即使你退出 shell, 后台进程也不会挂掉。
其中 -h 参数可以让 disown 在终端退出之后才生效。

vim 用户必须了解的 的 motion 和 operation

https://www.barbarianmeetscoding.com/boost-your-coding-fu-with-vscode-and-vim/editing-like-magic-with-vim-operators/

awk 不定长句子的最后一个单词:

1
awk '{ print $(NF) }'

NF 表示这行句子的字段数。

vmtouch: 一个可以分析/控制文件系统缓存的工具

我拥有很多 roamXXXX.org 文件, 还有一个超级大的 org-journal文件,每当我第一次用emacs打开这些大文件后,感受到明显的卡顿,我认为这明显的卡顿其中从磁盘冷加载文件贡献了 30% 的卡顿,然后就是解析大文件,格式化和 highlight 贡献了 70% 的卡顿。于是我想让电脑在第一次开机的时候,将这些预读一下,旁加载到page cache里。最简单粗暴的方法,就是写个循环,把这些文件都 cat * > /dev/null, 后来找到了更为优雅的工具: vmtouch
https://hoytech.com/vmtouch/

1
2
3
vmtouch -vt ~/.emacs.d/
vmtouch -vt ~/org/roam/
vmtouch -vt ~/org/daily/

vmtouch 可以将文件 touch 进内存, 也可以将内存中的文件缓存 evict 出内存。

vmtouch 的用了这些系统调用:

1
2
3
4
5
6
#include <sys/mman.h>
int mincore(void *addr, size_t length, unsigned char *vec);

#include <fcntl.h>
int posix_fadvise(int fd, off_t offset, off_t len, int advice);

scrcpy 控制安卓手机

我拥有一个安卓手机,没有 root,今天想通过 Linux 系统来控制手机,于是折腾了一下,找到了 scrcpy 这个包:

1
2
3
❯ sudo pacman -Ss scrcpy
archlinuxcn/scrcpy 1.19-1 [installed]
    Display and control your Android device

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,需要这个包

1
2
3
4
❯ sudo pacman -Sii ddcutil
Repository      : extra
Name            : ddcutil
Description     : Query and change Linux monitor settings using DDC/CI and USB.

然后 load i2c-dev module

1
modprobe i2c-dev

现在 ddcutil 就可以使用了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  ~
❯ sudo ddcutil capabilities | grep "Feature: 10"
   Feature: 10 (Brightness)
  ~
❯ sudo ddcutil getvcp 10
VCP code 0x10 (Brightness                    ): current value =    50, max value =   100
  ~
❯ sudo ddcutil setvcp 100
Missing argument(s)
  ~
❯ sudo ddcutil setvcp 10100
  ~
❯ sudo ddcutil capabilities | grep "Feature: 10"
   Feature: 10 (Brightness)
  ~
❯ sudo ddcutil getvcp 10
VCP code 0x10 (Brightness                    ): current value =    50, max value =   100
  ~
❯ sudo ddcutil setvcp 10 100
  ~
❯ sudo ddcutil setvcp 10 20
  ~
❯ sudo ddcutil setvcp 10 100

大功告成,以后我再也不用伸胳膊去够显示器后面的调节按钮了。
:-D

Wikiwand: Wikipedia Modernized, 一个可以让你的 wikipedia 页面更好看的 chrome 插件!

https://chrome.google.com/webstore/detail/wikiwand-wikipedia-modern/emffkefkbkpkgpdeeooapgaicgmcbolj

使用 kdeconnect-cli 为手机分享文件或文字

因为懒得去动鼠标/触摸板来 操作 kdeconnect 的图形界面,所以研究了一下如何在终端里将文件分享给手机。

1
2
3
4
5
kdeconnect-cli -l
kdeconnect-cli -a --id-only
kdeconnect-cli -d ${deviceid} --ping
kdeconnect-cli -d ${deviceid} --share ${realpath_of_file}
kdeconnect-cli -d ${deviceid} --share-text ${text} # 这会把文本分享给手机的粘贴板。

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 导出为图片

  1. 用 google-chrome
1
google-chrome-stable --headless --disable-gpu --virtual-time-budget=10000 --window-size=3840,2160 --screenshot https://www.google.com

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

  1. 用 wkhtmltoimage
1
wkhtmltoimage --width 1980 --height 1024  --quality 100 --javascript-delay 10000 https://www.google.com google.png

Emacs 将 org-journal-entry 同步到 telegram channel 里

我使用 org-journal 来记录生活,但是 org-journal 是离线的,我创建了个 bot 来将单条 org-journal-entry 同步到 channel里。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
(defun exec/get-org-entry-summary ()
  (interactive)
  (setq urlraw (format
    "https://api.telegram.org/bot%s/[email protected]%s&text="
    (read-file "/home/vory/.emacs.d/config/tgsync.token")
    (read-file "/home/vory/.emacs.d/config/chatid.priv")
    ))
  (setq urlraw (concat urlraw   (buffer-substring (line-beginning-position) (line-end-position))))

  (message urlraw)
  (setq urlq (url-encode-url urlraw))

  (setq url-proxy-services
  '(("http" . "127.0.0.1:1081")
	("https" . "127.0.0.1:1081")))
  (url-retrieve-synchronously urlq)
  (message "sync to telegram channel success"))

茴香豆的茴有几种写法之 VIM 有哪几种退出方式?

  • :wq / ZZ / :x
  • :q! / ZQ

日志里面第一列是 ip, 查询出现次数前 10 的 ip

1
cat xxx.log | awk '{ print $1 }' | sort -n | uniq -c | sort -r -k1 | head 10

grep pdf 文件

ripgrep-all

为 tmux 的 pane 名称设置不同的 emoji 后缀

生活要过的多姿多彩,同样的,我的终端也必须多姿多彩。于是我给 tmux的panel添加了随机的emoji后缀
写一个shell脚本,放进我喜欢的emoji

1
2
3
4
EMOJIS=(😀 😃 😄 😁 😆 😅 🤣 😂 🙂 🙃 😉 😊 😇 🥰 😍 🤩 😘 )
SELECTED_EMOJI=${EMOJIS[$RANDOM % ${#EMOJIS[@]}]};
echo -n $SELECTED_EMOJI

然后在tmux里这样设置pane的名称,:

1
set-option -g automatic-rename-format '#{b:pane_current_path}[#(/home/vory/Dotfiles/tmux/pick.sh)]'

大功告成!

direvent:

GNU direvent - Summary [Puszcza]

OCR 应用: tesseract

有时候身边的同事在排查问题的时候,会从用户那里得到图片形式的hash,为了debug,我本可以手工将图片形式的哈希转化为文本形式的,可是我实在是嫌麻烦,于是玩了下这个从 2006 年开始由Google maintain 的 OCR工具: tesseract-ocr/tesseract

ArchLinux 下所需的包

tesseract

1
> sudo pacman -S tesseract tesseract-data-chi_sim tesseract-data-chi_tra tesseract-data-eng

第一个是主程序,其他的都是由Google训练好的中文和英文模型库。
tesseract 的使用规则是这样的:

1
2
3
4
 tesseract FILE OUTPUTBASE [OPTIONS]... [CONFIGFILE]...
 # If FILE is stdin or - then the standard input is used.
 # If OUTPUTBASE is stdout or - then the standard output is used.

我的使用流程是: 从屏幕上截图,截图会自动保存到粘贴版,然后:

1
xclip -sel clip -target image/png -o | tesseract stdin stdout -l chi_sim -c preserve_interword_spaces=1

如果不加preserve_interword_spaces=1 的话,识别出的结果就会有烦人的空格。

结果很准确,甚至是同时有中文英文和符号的图片都能识别!

使用 sed 获取一个文件位于两个关键词之间的内容

比如:

> cat file.txt
first line :head
second line
third line
apple
forth line
...
tiger
last line
tail
1
2
3
4
5
6
> sed -n '/apple/,/tigger/p'  file.txt
apple
forth line
...
tiger

goland 缺失的功能

我用goland开发公司的项目,很喜欢goland的rename usages of 变量/函数 A to 变量/函数 B的功能,但是我却不能对 import 这么做, 要是想改变整个项目都某一个包的引用,不得不使用 sed:

1
find . -name '*.go' -type f -exec sed -i 's/tg-service/tg-service\/bridge/g' {} ';'

*nix 环境,快速生成大量随机的 leetcode 测试用例

当我在 leetcode做了一道算法题后, 我会先在心里考虑一下输入的边界情况(或者非法输入),时间复杂度(要是数据里过大并且我的算法时间复杂度太差就会 Time Limit Exceed)。

所以我要么手动在 test cases 里手写测试用例, 要么用 linux 下这么几个有用的命令随机生成大量的测试用例:

1
2
3
4
5
6
seq  # print a sequence of numbers

shuf #  generate random permutations

paste #   merge lines of files

用这三个简单的工具, 一般就能生成我想要的测试数据了。
比如我想生成一个数组, 数组的每个元素都是数字,整个数组要是 unsorted:

1

要是想要超大的数据量, 我一般会写到 /tmp/ 里,再配合 xclip 将内容读进到 粘贴板, 最终粘贴到网页里去

https://leetcode.com/problems/combination-sum/solution/

1
2
3

seq 100 | shuf | paste -s -d ,

我喜欢用 printf 配合这些工具输出我想要的格式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
> cat gen.sh
N=100
if [[ $# -eq 1 ]];then
    N=$1
fi
for n in $(seq $N) ;
do
    if [[ $(($RANDOM % 3 )) -eq 0 ]];then
        echo $n
    fi
done


> printf "[%s]\n" "$(./gen.sh 365 | paste -s -d , )"

[3,10,11,18,21,22,32,37,40,44,45,46,48,50,52,53,55,57,61,63,64,65,66,68,69,76,79,90,91,93,95,96,99,100]

> printf "[%s]\n" "$(./gen.sh 365 | paste -s -d , )" | xclip -sel clip
# 生成随机结果, 并且复制到粘贴板

心中的疑惑

  1. 在终端里快速生成大量随机数的最佳实践是什么?

gorm 链接 MySQL 处理 Error 1390 错误

我在公司负责的项目中使用了 gorm, 有一次 批量插入数据时遇到了 1390 :too many placeholders
所以我不得不减少数据量,为了解决问题将代码这样修改:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import(
    gmysql "github.com/go-sql-driver/mysql"
)
type Transactions []Transaction

func (ts Transactions) Insert() error {
	if len(ts) == 0 {
		return nil
	}

	err := db.Clauses(clause.OnConflict{
		DoNothing: true,
	}).Create(&ts).Error
	if err == nil {
		return nil
	}

	var mysqlErr *gmysql.MySQLError
	if errors.As(err, &mysqlErr) && mysqlErr.Number == 1390 {
		mid := len(ts) / 2
		if err := ts[:mid].Insert(); err != nil {
			return err
		}
		if err := ts[mid:].Insert(); err != nil {
			return err
		}
		return nil
	}
	return err
}

https://stackoverflow.com/questions/18100782/import-of-50k-records-in-mysql-gives-general-error-1390-prepared-statement-con

Share on

EXEC
WRITTEN BY
EXEC
Evil EXEC