Linux如何获取进程的基地信息

1. 问题执行程序时,与程序同目录下存在一 config/ 目录,其中存放了 json 格式的配置文件。进行部署时需要将程序和 config/ 目录放在同一位置。那么,问题来了,如何保证不管这个程序部署到什么位置,不管以什么方式运行,程序自己都能访问到配置文件呢?
解决问题之前,先说一下进程的工作目录——current working directory。
2. 什么是进程的工作目录进程的工作目录是指进程的调用者在启动进程对应的程序时, 调用者所在的目录 。比如说,在 /home/sdc/ 目录下有一个可执行程序 hello-world。如果在根目录下启动 hello-world,那么 hello-world 进程的工作目录为根目录 / 。如果在 /home/sdc 目录下启动 hello-world,那么其工作目录为 /home/sdc。
linux c 中,有两个函数可以获取进程工作目录:getcwd() 和 readlink()。
2.1 getcwd()man 3 getcwd():https://man7.org/linux/man-pages/man2/getcwd.2.html
#include char *getcwd(char *buf, size_t size);该函数将获取到的进程工作目录的绝对路径存储在形参 buf 中。同时也会返回一个指针,指针指向的内容和 buf 存储的内容相同。如果路径的长度比 size 大,那么该函数返回为 null。
2.2 readlink()man 2 readlink:https://www.man7.org/linux/man-pages/man2/readlink.2.html
#include ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);该函数用于获取符号链接所指的文件。借助 /proc/self/cwd,即 pathname = /proc/self/cwd,readlink() 即可获得当前进程的工作目录。
该函数同样将进程工作目录的绝对路径存储在形参 buf 中,并返回存储的路径长度。但是,buf 中存储路径不带字符串结束符 '�'。而且,如果返回的长度和 bufsiz 相同,那么路径信息很可能被截取了。
2.3 简单例程hello-world.c:
#include #include #include #include int main(int argc, char *argv[]){ char work_dir[64] = {0}; int dir_size = 0; getcwd(work_dir, sizeof(work_dir))) printf(getcwd:%sn, work_dir); memset(work_dir, 0, sizeof(work_dir)); dir_size = readlink(/proc/self/cwd, work_dir, sizeof(work_dir)); work_dir[dir_size] = '�'; printf(readlink:%sn, work_dir); return 0;}执行结果:
3. 获取进程对应程序的绝对路径如果想要解决文章开头提出的问题,那么进程需要获取程序所在的绝对路径。该功能通过 readlink(const char *pathname, char *buf, size_t bufsiz)实现。不过 pathname 不再是 /proc/self/cwd,而是 /proc/self/exe 。
开箱即用代码 :
#include #include #include #include #include #include #define config_filename ./config/psl.json//get current process elf absolute pathstatic int32_t curr_elf_abs_path_get(int8_t *path_buf, int32_t buf_size){ ssize_t len = 0; int32_t i = 0; len = readlink(/proc/self/exe, path_buf, buf_size); if(-1 == len) { perror(readlinkn); return -1; } if(len == buf_size) { printf(warn:path may be truncatedn); } //from last to head, find first '/' for(i = len; i > 0; i--) { if(path_buf[i] == '/') { path_buf[i + 1] = '�'; break; } } return 0;}int main(int argc, char *argv[]){ int8_t elf_path[128] = {0}; int8_t config_file_path[256] = {0}; int fd = -1; int32_t i = 0; int32_t ret = 0; ret = curr_elf_abs_path_get(elf_path, sizeof(elf_path)); if(0 != ret) { printf(get exe path failedn); return -1; } printf(current process exe absolute path:%sn, elf_path); sprintf(config_file_path, %s%s, elf_path, config_filename); fd = open(config_file_path, o_rdwr); if(-1 == fd) { perror(open); return -1; } printf(open %s successn, config_file_path); close(fd); return 0;}cmakelists.txt:
cmake_minimum_required(version 3.12)project(exe-abs-path c)set(cmake_verbose_makefile on)add_executable(${project_name} main.c)执行结果:
4. 总结我当然可以借助 shell 脚本解决该问题。可是,我还是喜欢让程序自己”实现“该功能,这样我在部署和使用时会方便很多。
5. 说明/proc/self/ 目录中存放了当前进程的很多有用信息。
/proc/self/fd/:进程打开的文件描述符;
/proc/self/cmdline:进程被执行时,命令行中输入的命令;
/proc/self/task:进程中包含的线程 id;
/proc/self/environ:进程运行时的环境变量信息。

漏电开关测试仪图解_漏电保护测试仪怎么用
74系列芯片功能大全
阅兵直播采用的增强现实技术是如何实现的?
贵州首条国际互联网数据专用通道顺利通过竣工验收
使用STM32F10xxx SWJ引脚作为标准IO
Linux如何获取进程的基地信息
什么是热回路
缝合线线径检测设备
WTN6语音芯片在指静脉门锁上的应用方案
PADS中如何实现零件的自由旋转
华为P10都已经发布了!华为mate10:你在多远的未来?
Arduino程序光传感器感测模块简介
Cloud VR发展进入快车道,规模商用加速
NAND形成规模,产能过剩的风险日益高企
一文读懂Git重要概念和常用指令
鸿蒙系统开源代码 鸿蒙系统官网
运放参数的详细解释和分析
uCOS-II的介绍和uCOS-II在单片机使用中的一些特点资料概述
MCU是本轮汽车芯片短缺的“重灾区”
声光调制器的原理 声光调制器的主要应用领域