proc文件系统
proc文件系统
/proc/self/exe 是 Linux 系统中一个特殊的符号链接,它指向 当前进程的可执行文件 的绝对路径。这个机制在多种场景下非常有用,以下是它的主要用法和示例:
1. 获取当前程序的绝对路径
最常见的用途是 动态获取当前运行程序的完整路径,无需硬编码路径或依赖 argv[0](可能不准确)。
C 语言示例
c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <unistd.h>
#include <stdio.h>
int main() {
char exe_path[1024];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len != -1) {
exe_path[len] = '\0';
printf("Current executable path: %s\n", exe_path);
} else {
perror("readlink");
}
return 0;
}
输出示例:
text
1
Current executable path: /home/user/my_program
2. 检查程序是否被符号链接调用
通过比较 /proc/self/exe 和 argv[0],可以判断程序是否通过符号链接启动:
c
1
2
3
if (strcmp(exe_path, argv[0]) != 0) {
printf("Called via symlink: %s\n", argv[0]);
}
3. 重新执行自身(Self-Exec)
某些程序需要 重新启动自己(如升级后),此时可以通过 /proc/self/exe 获取自己的路径:
c
1
execl(exe_path, exe_path, NULL);
4. 安全验证
在安全敏感场景中,验证程序的真实路径是否未被篡改:
c
1
2
3
4
if (strstr(exe_path, "/expected/path/") == NULL) {
fprintf(stderr, "Security alert: Binary path mismatch!\n");
exit(1);
}
5. 动态库中获取主程序路径
动态库(.so)可以通过 /proc/self/exe 获取加载它的主程序路径,用于插件或依赖管理。
6. 容器环境中的注意事项
在 Docker 或容器中,/proc/self/exe 仍然指向容器内的路径,但需注意:
- 如果容器内路径与宿主机不同,可能需要额外处理。
- 某些容器安全策略(如
proc文件系统只读)可能限制访问。
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
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
static int count = 0;
printf("Process started, count = %d\n", count);
count++;
if (count < 3) {
char exe_path[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len == -1) {
perror("readlink");
exit(EXIT_FAILURE);
}
exe_path[len] = '\0';
printf("Re-executing: %s\n", exe_path);
execv(exe_path, argv); // argv[0] 是程序名,argv 传递原始参数
perror("execv failed");
exit(EXIT_FAILURE);
}
printf("Final run complete. Exiting.\n");
return 0;
}
1
2
3
4
5
6
7
8
9
10
Re-executing: /home/gc/Desktop/test
Process started, count = 0
Re-executing: /home/gc/Desktop/test
Process started, count = 0
Re-executing: /home/gc/Desktop/test
Process started, count = 0
Re-executing: /home/gc/Desktop/test
Process started, count = 0
Re-executing: /home/gc/Desktop/test
...
This post is licensed under CC BY 4.0 by the author.