FAQs about System Programming
- x86_64 平台下,system-calls 最多可以有几个参数?
1 | 6 |
1 | 6 |
LLVM 是 Low-Level Virtual Machine 的简写,但事实上它与虚拟机关系不大。我们更熟悉它是一套工具链,包括 clang /'klæŋ/
, lld, lldb 等等。接触 LLVM 是因为 Mesa llvmpipe 使用 LLVM, 还有 AMDGPU 和 Radeon 的编译器后端都使用 LLVM IR,所以要编译 Mesa 的 -Dgallium-drivers=llvmpipe,radeonsi
都依赖于 LLVM 的诸多组件, 构建 Linux 内核的 eBPF 程序也依赖 LLVM, 构建 perfetto 也依赖 LLVM。这里主要记录 LLVM 的构建和使用的一些问题。
POSIX Basic Regular Expression
POSIX Extended Regular Expression
shorthand | equivalence |
---|---|
\w |
[[:alnum:]_] |
\W |
[^[:alnum:]_] |
\s |
[[:space:]] |
\S |
[^[:space:]] |
shorthand | matches |
---|---|
\b |
position at a word boundary |
\B |
position not at a word boundary |
\< |
position at the start of a word |
\> |
position at the end of a word |
\` (backtick) |
position at the start of subject string |
\' (single quote) |
position at the end of subject string |
grep
multiline match-P
: 使用 Perl 正则表达式扩展-z
: 让 grep 把输入的行看成是一个多个行的集合,一个整体.*?
: 后面的 ?
表示 .*
按 non-greedy 模式匹配,也就是尽可能少(短)的匹配(?s)
: 让 .
匹配任意字符,包括 \n
(aka. PCRE_DOTALL)Linux 下的 Shell 有很多, sh, bash, csh, zsh 等, 这里主要记录一下 bash 和 zsh 的一些不同之处
1 | ${var:+WORD} |
如果 var
没有设置或为空,则这个变量展开为 Nothing (注意:不是空 empty, 是 nothing), 如果被设置了(不包括被设置成空),它展开为 +
后面的 WORD.
如果冒号被省略,则 var
即使被设置为空,它也展开为 +
后面的 WORD
1 | ${!var} |
如果 var
的值是 MESA_DEBUG
, 那么这个形式展开后是变量 MESA_DEBUG
的值,例如 export MESA_DEBUG=1
, var=MESA_DEBUG
, 则最后的展开结果是 1
1 | ${var@Q} |
带 @Q
指变量展开后的值被单引号引起来,例如 export ABC=abc
, echo "ABC=${ABC@Q}"
的结果是 ABC='abc'
Linux 下的文本处理三剑客: grep, sed, awk, 除了它们其实还有一些小巧的命令,如 tr
, cut
也可以帮助我们快速处理和格式化文本。
下面以一个例子为例。
在 Linux 内核源码目录下,搜索 drivers/gpu/drm
下所有的 DRIVER_NAME
定义,并排序后格式化输出
命令如下:
1 | rg '#define DRIVER_NAME' drivers/gpu/drm --no-heading \ |
rg
(ripgrep) 比 grep 更快,更强大tr
在不带任何选项时,默认执行替换,例子是中将 tab 替换成 空格, -s
表示 squeeze-repeats
, 就是去掉重复的字符,例如多个空格只保留一个awk
天生支持 C-Style printf输出结果:
1 | drivers/gpu/drm/solomon/ssd130x.c:#define DRIVER_NAME "ssd130x" |
1 | drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h #define DRIVER_NAME "amdgpu" |
crontab -e
(添加定时任务), 不光可以添加周期性的定时任务,也可以添加开机时一次性任务
1 | @reboot /home/luc/mystart.sh |
crontab 是每用户的, 就是说当前用户设定的任务,只有当前用户的权限,所以如果有些情况下任务执行需要 root 权限,就需要切换到 root 用户后 crontab -e
Highly recommended 3 utilities:
eisvogel 要求一个完整的 TexLive 的安装环境,但通常像 CentOS 这样的 Linux 发行版自带的 TexLive 并不完整。
texlive.iso
将 TexLive 的镜像下载并挂载后,通过顶层目录下的 install-tl
这个 Perl 脚本程序安装,整个安装过程要注意以下几点。
假设在 Linux 下,通过 root 用户或 sudo
挂载镜像文件
1 | mkdir -p /mnt/iso |
TexLive 的 installer 是一个 perl script, 提供 text mode 和 GUI mode 两种安装模式.
1 | ======================> TeX Live installation procedure <===================== |
1 | Options customization: |
最好勾选此选项,避免使用 TexLive 时各种 Not Found
, 原因是 TexLive 默认安装路径并不是标准 Linux 可执行程序的路径(如 /usr/bin
), 而是 /usr/local/texlive
, 如在 x86_64 安装 texlive2022.iso
, 则可执行程序被安装在 /usr/local/texlive/2022/bin/x86_64-linux
. 假如不想因为该路径没有在 PATH
里,最好就是在安装时直接在 /usr/bin
下创建相应符号链接。
在使用 xelatex, pdflatex 等 latex 程序时,可以常常遇到类似
! LaTeX Error: File 'fontawesome.sty' not found
xxx.sty 这样的报错,一般是缺少某个 texlive 包,但 texlive 的包太多了,如果懒得一个一个安装,可以
sudo apt install texlive-full
find
命令find
命令用来在目录树里查找文件。本文主要介绍 GNU find. 它从每个 starting-point 开始递归搜索,通过求值 expression 的真值来确定输出结果。
find
的命令行组成只在当前目录搜索(不递归)不以 f 或 g 或 h 开头的目录
find . -maxdepth 1 -name '[^fgh]*' -type d
-type d
: 找目录-type f
: 找文件(不包括 symbolic link)-type l
: 找符号链接文件排除/proc 和 /tmp 这两个目录
find / -path /proc -prune -o -path /tmp -prune -o -name "README.md"
-prune
告诉 find 跳过前面的目录,也可以用 \( -o \)
将多个 -path
合并,只保留一个 -prune
只在当前目录查找除了指定及隐藏目录以外的所有目录,打印并删除
find -maxdepth 1 \( -path ./gh -o -path ./aaa -o -path ./mesa-install -o -path ./1.3.290.0 -o -path ./1.3.280.1 \) -prune -o -type d ! -name ".*" -print -exec rm -rf {} \;
.*
, .
在 shell 里不是通配符-print
: 不让 ./gh
, ./aaa
这些目录出现在 find
命令的输出结果中查找 ~/gh 目录下只有文件属主(u)有执行权限(x)的文件 (精确匹配文件的 permission bits)
find ~/gh -perm u=x -type f
查找 ~/gh 目录下文件属主(u)有执行权限(x) 的文件(组用户(g)或其它用户(o)可能有或没有执行权限)
find ~/gh -perm -u=x -type f