Skip to content

Commit 30c97e9

Browse files
committed
add blog: completion for patchelf in zsh
1 parent ebdd4cc commit 30c97e9

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

blog/debuginfod.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
1010
## 背景
1111

12-
今年打宁波赛的时候,libc使用了上古的`2.35-0ubuntu3.1_amd64`,glibc-all-in-one下不到,
12+
今年打宁波赛的时候,libc使用了难以下到的`2.35-0ubuntu3.1_amd64`,glibc-all-in-one下不到,
1313
问学长,学长也没有,只能使用[Roderick的容器](https://github.com/RoderickChan/docker_pwn_env)
1414

1515
因为没仔细看,导致容器内的pwndbg更新了,而更新又需要容器里没有的sudo,导致容器里也无法调试,

blog/patchelfForZsh.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# 修复zsh上patchelf自动补全的错误
2+
3+
如果你使用zsh来作为你的主力shell的话,那你在使用patchelf的时候一定受到过这样的困扰:
4+
在尝试补全`--set-interpreter`后的参数时,按下tab就变成了 *_arguments:463: command not found: dynamic*
5+
在尝试补全`--replace-needed`后的参数时,又变成了 *_arguments:463: command not found: LIB_ORIG*
6+
这个问题已经存在了一年多,也困扰了我很久
7+
8+
直到有人就因为这个小事,不愿尝试zsh,那不是丢了西瓜捡芝麻,zsh这么好用的说...
9+
10+
## 前情提要
11+
12+
早在21年,**@Y7n05h**[尝试为zsh增加补全支持](https://github.com/NixOS/patchelf/issues/310)
13+
但随着他不再使用patchelf,他也停止了补全脚本的编写
14+
15+
23年,**@Freed-Wu**接过了任务,完成了补全脚本并提交了PR,但是他的脚本并不完全正确,
16+
导致了zsh无法正确补全
17+
18+
## 修复
19+
20+
首先就是针对上面两个常用arg进行修复,我先尝试问了下ChatGPT,
21+
[文件](https://github.com/NixOS/patchelf/blob/master/completions/zsh/_patchelf#L5)中,
22+
`INTERPRETER`是消息,`dynamic loader`是描述,而`_files`是命令,那为什么无法运行呢?
23+
24+
查阅别人写的[zsh自动补全脚本入门](https://chuquan.me/2020/10/02/zsh-completion-tutorial/)
25+
发现多了一个参数,正确示例是`-OPT[DESCRIPTION]:MESSAGE:ACTION`,那么修复起来就很简单了,
26+
只要把多余的参数去掉,换上`_files`,就能正常运行了
27+
28+
## 增强
29+
30+
patchelf还可以`--print-needed`,那么是不是可以把打印出来的依赖,作为`--replace-needed`的补全呢?
31+
在ChatGPT的帮助下,这下可以在判断对象文件是elf的情况下,按tab补全它的依赖了
32+
33+
但是,ChatGPT给的是类似与bash与zsh脚本的混合,那既然都选了zsh了,就替换为zsh语法吧
34+
35+
跟着[别人的指引](https://github.com/goreliu/zshguide),我又把补全脚本完善了一遍,
36+
加速了条件的判断,也提高了对文件范围的判断,
37+
详细可见这个[commit](https://github.com/RocketMaDev/patchelf/commit/61a49b905c2eb329848349dc8c0eb6c5fa873aa7)
38+
39+
## 安装使用
40+
41+
本文对应的PR: https://github.com/NixOS/patchelf/pull/552
42+
1. `echo $fpath`列出补全文件搜索目录
43+
2. 找到`_patchelf`文件所在位置(如在我这里是在`/usr/local/share/zsh/site-functions`中)
44+
3. 从我的仓库中下载`_patchelf`并替换你的`_patchelf`
45+
```sh
46+
curl -o /path/to/your/_patchelf https://raw.githubusercontent.com/RocketMaDev/patchelf/master/completions/zsh/_patchelf
47+
# 可能需要root
48+
# 或者手动复制并覆写
49+
```
50+
4. 执行`unfunction _patchelf && autoload -U _patchelf`或重启shell
51+
5. (可选)在Arch Linux上,只要更新patchelf,补全脚本就会被覆盖,因此可以写一个函数,
52+
放在`~/.zshrc`中,方便在patchelf更新的时候再次覆盖脚本
53+
```zsh
54+
update_patchelf() {
55+
sudo curl -o /usr/share/zsh/site-functions/_patchelf "https://raw.githubusercontent.com/RocketMaDev/patchelf/master/completions/zsh/_patchelf"
56+
unfunction _patchelf && autoload -U _patchelf
57+
}
58+
```
59+
推荐patch对象前置,例如`patchelf $ELF --replace-needed [TAB]`,这样方便补全,
60+
否则就需要先留个空位,然后写上要替换的so的路径,写上patch对象,再回过去补全
61+

0 commit comments

Comments
 (0)