linux根據程序號PID查詢啟動程式的全路徑(程式實現根據PID程序號得到程序名字或根據程序名字取得程序號)
Password:
[email protected]:~ cd app
[email protected]:~/app ps
PID TTY TIME CMD
749 ttyp2 00:00:00 login
750 ttyp2 00:00:00 sh
752 ttyp2 00:00:00 ps
[email protected]:~/app ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:01 init
2 ? S 0:00 [kthreadd]
3 ? S 0:00 [ksoftirqd/0]
4 ? S 0:00 [kworker/0:0]
5 ? S< 0:00 [kworker/0:0H]
6 ? S 0:00 [kworker/u2:0]
7 ? S< 0:00 [khelper]
8 ? S 0:00 [kdevtmpfs]
9 ? S 0:00 [kworker/u2:1]
167 ? S< 0:00 [writeback]
170 ? S< 0:00 [bioset]
171 ? S< 0:00 [crypto]
173 ? S< 0:00 [kblockd]
186 ? S 0:00 [khubd]
209 ? S< 0:00 [cfg80211]
210 ? S 0:00 [kworker/0:1]
334 ? S 0:00 [gatekeeper/0]
336 ? S 0:00 [kswapd0]
337 ? S 0:00 [fsnotify_mark]
487 ? S< 0:00 [ipv6_addrconf]
493 ? S< 0:00 [deferwq]
498 ? S 0:00 [ubi_bgt0d]
507 ? S 0:00 [ubifs_bgt0_0]
520 ? Ss 0:00 /sbin/syslogd
522 ? Ss 0:01 /sbin/klogd
564 ? Ss 0:00 /usr/sbin/udhcpd -S /etc/udhcpd.conf
569 ? Ss 0:00 pure-ftpd (SERVER)
572 ? Ss 0:00 pure-uploadscript -B -u 0 -g 0 -r /usr/sbin/ftp_upload_script
575 ? Ss 0:00 /usr/sbin/inetd
607 ttyS0 Ss+ 0:00 /sbin/getty -L 115200 ttyS0 vt100
737 ? Ss 0:00 telnetd -i
738 ttyp1 Ss 0:00 /bin/login
739 ttyp1 S 0:00 -sh
742 ? Ss 0:00 telnetd -i
743 ttyp0 Ss 0:00 /bin/login
744 ttyp0 S+ 0:00 -sh
747 ttyp1 S+ 0:00 ./zb_terminal -t
748 ? Ss 0:00 telnetd -i
749 ttyp2 Ss 0:00 /bin/login
750 ttyp2 S 0:00 -sh
753 ttyp2 R+ 0:00 ps ax
[email protected]:~/app cd ../
[email protected]:~ ls
app backup cfg default font lib log logfile other sys test tmn698 update usr
[email protected]:/proc/747 ls -ail
total 0
1069 dr-xr-xr-x 7 root root 0 Apr 9 13:32 .
1 dr-xr-xr-x 55 root root 0 Jan 1 1970 ..
1096 -r-------- 1 root root 0 Apr 9 13:34 auxv
1110 --w------- 1 root root 0 Apr 9 13:34 clear_refs
1084 -r--r--r-- 1 root root 0 Apr 9 13:32 cmdline
1099 -rw-r--r-- 1 root root 0 Apr 9 13:34 comm
1117 -rw-r--r-- 1 root root 0 Apr 9 13:34 coredump_filter
1104 lrwxrwxrwx 1 root root 0 Apr 9 13:34 cwd -> /home/app
1095 -r-------- 1 root root 0 Apr 9 13:34 environ
1106 lrwxrwxrwx 1 root root 0 Apr 9 13:34 exe -> /home/app/zb_terminal
1091 dr-x------ 2 root root 0 Apr 9 13:34 fd
1092 dr-x------ 2 root root 0 Apr 9 13:34 fdinfo
1098 -r--r--r-- 1 root root 0 Apr 9 13:34 limits
1102 -r--r--r-- 1 root root 0 Apr 9 13:34 maps
1103 -rw------- 1 root root 0 Apr 9 13:34 mem
1108 -r--r--r-- 1 root root 0 Apr 9 13:34 mountinfo
1107 -r--r--r-- 1 root root 0 Apr 9 13:34 mounts
1109 -r-------- 1 root root 0 Apr 9 13:34 mountstats
1094 dr-xr-xr-x 4 root root 0 Apr 9 13:34 net
1093 dr-x--x--x 2 root root 0 Apr 9 13:34 ns
1115 -rw-r--r-- 1 root root 0 Apr 9 13:34 oom_adj
1114 -r--r--r-- 1 root root 0 Apr 9 13:34 oom_score
1116 -rw-r--r-- 1 root root 0 Apr 9 13:34 oom_score_adj
1112 -r--r--r-- 1 root root 0 Apr 9 13:34 pagemap
1097 -r--r--r-- 1 root root 0 Apr 9 13:34 personality
1105 lrwxrwxrwx 1 root root 0 Apr 9 13:34 root -> /
1111 -r--r--r-- 1 root root 0 Apr 9 13:34 smaps
1072 -r--r--r-- 1 root root 0 Apr 9 13:32 stat
1101 -r--r--r-- 1 root root 0 Apr 9 13:34 statm
1073 -r--r--r-- 1 root root 0 Apr 9 13:32 status
1100 -r--r--r-- 1 root root 0 Apr 9 13:34 syscall
1090 dr-xr-xr-x 3 root root 0 Apr 9 13:34 task
1113 -r--r--r-- 1 root root 0 Apr 9 13:34 wchan
[email protected]:/proc/747
[email protected]:/proc/747 /proc/747/status
-sh: /proc/747/status: Permission denied
[email protected]:/proc/747 cd ../../
[email protected]:/ cat /proc/747/status
Name: zb_terminal
State: S (sleeping)
Tgid: 747
Ngid: 0
Pid: 747
PPid: 739
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 32
Groups: 0
VmPeak: 1824 kB
VmSize: 1820 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 452 kB
VmRSS: 448 kB
VmData: 160 kB
VmStk: 136 kB
VmExe: 4 kB
VmLib: 1416 kB
VmPTE: 6 kB
VmSwap: 0 kB
Threads: 1
SigQ: 0/974
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000001fffffffff
CapEff: 0000001fffffffff
CapBnd: 0000001fffffffff
Cpus_allowed: 1
Cpus_allowed_list: 0
voluntary_ctxt_switches: 64
nonvoluntary_ctxt_switches: 1
程式:
切記:此方法有一個弊端,就是程序名字如果太相似會產生問題,比如 test_commonfunc_A 和test_commonfunc_B 當前執行的程序包含這兩個,而test_commonfunc_A 程序的程序號是853, 兩個程序名字太相似不能用此方法,
舉例會產生如下
[email protected]:~/app cat /proc/853/status
Name: test_commonfunc
State: S (sleeping)
Tgid: 853
Ngid: 0
Pid: 853
PPid: 750
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 32
Groups: 0
VmPeak: 1836 kB
VmSize: 1832 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 568 kB
VmRSS: 568 kB
VmData: 160 kB
VmStk: 136 kB
VmExe: 12 kB
VmLib: 1416 kB
VmPTE: 8 kB
VmSwap: 0 kB
Threads: 1
Liunx中 通過程序名查詢程序PID可以通過 pidof [程序名] 來查詢。反過來 ,相同通過PID查詢程序名則沒有相關命令。
在linux根目錄中,有一個/proc的VFS(虛擬檔案系統),系統當前執行的所有程序都對應於該目錄下的一個 以程序PID命名的資料夾 ,其中存放程序執行的N多資訊。其中有一個status檔案,cat顯示該檔案, 第一行的Name 即為程序名。
開啟stardict程式,程序名為stardict;
shell中分別根據Pid獲取程序名、根據程序名獲取Pid
1)查詢stardict的pid:pidof stardict
2)根據1)的pid查詢程序名: grep "Name:" /proc/5884/status
應用:kill一個程序需要指定該程序的pid,所以我們需要先根據程序名找到pid,然後再kill;
killall命令則只需要給定程序名即可,應該是封裝了這個過程。
C程式中實現上述過程
1 #include <sys/types.h> 2 #include <dirent.h> 3 #include <stdio.h> 4 #include <string.h> 5 6 #define BUF_SIZE 1024 7 8 void getPidByName(char* task_name) 9 { 10 DIR *dir; 11 struct dirent *ptr; 12 FILE *fp; 13 char filepath[50];//大小隨意,能裝下cmdline檔案的路徑即可 14 char cur_task_name[50];//大小隨意,能裝下要識別的命令列文字即可 15 char buf[BUF_SIZE]; 16 dir = opendir("/proc"); //開啟路徑 17 if (NULL != dir) 18 { 19 while ((ptr = readdir(dir)) != NULL) //迴圈讀取路徑下的每一個檔案/資料夾 20 { 21 //如果讀取到的是"."或者".."則跳過,讀取到的不是資料夾名字也跳過 22 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) continue; 23 if (DT_DIR != ptr->d_type) 24 continue; 25 26 sprintf(filepath, "/proc/%s/status", ptr->d_name);//生成要讀取的檔案的路徑 27 fp = fopen(filepath, "r");//開啟檔案 28 if (NULL != fp) 29 { 30 if( fgets(buf, BUF_SIZE-1, fp)== NULL ){ 31 fclose(fp); 32 continue; 33 } 34 sscanf(buf, "%*s %s", cur_task_name); 35 36 //如果檔案內容滿足要求則列印路徑的名字(即程序的PID) 37 if (!strcmp(task_name, cur_task_name)) 38 printf("PID: %s\n", ptr->d_name); 39 fclose(fp); 40 } 41 42 } 43 closedir(dir);//關閉路徑 44 } 45 } 46 47 void getNameByPid(pid_t pid, char *task_name) { 48 char proc_pid_path[BUF_SIZE]; 49 char buf[BUF_SIZE]; 50 51 sprintf(proc_pid_path, "/proc/%d/status", pid); 52 FILE* fp = fopen(proc_pid_path, "r"); 53 if(NULL != fp){ 54 if( fgets(buf, BUF_SIZE-1, fp)== NULL ){ 55 fclose(fp); 56 } 57 fclose(fp); 58 sscanf(buf, "%*s %s", task_name); 59 } 60 } 61 62 void main(int argc, char** argv) 63 { 64 char task_name[50]; 65 pid_t pid = getpid(); 66 67 printf("pid of this process:%d\n", pid); 68 getNameByPid(pid, task_name); 69 70 /* 71 strcpy(task_name, argv[0]+2); 72 printf("task name is %s\n", task_name); 73 getPidByName(task_name); 74 */ 75 printf("task name is %s\n", task_name); 76 getPidByName(task_name); 77 sleep(15); 78 }
執行結果:
進入/proc/9674/status檢視檔案內容,一切對應。
Name: test
State: S (sleeping)
Tgid: 9674
Pid: 9674
PPid: 7438
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 256
Groups: 4 24 27 30 46 112 124 1000
VmPeak: 4340 kB
VmSize: 4336 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 600 kB
VmRSS: 600 kB
VmData: 184 kB
VmStk: 136 kB
VmExe: 4 kB
VmLib: 1920 kB
VmPTE: 32 kB
VmSwap: 0 kB
Threads: 1
SigQ: 0/15776
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
Seccomp: 0
Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1
nonvoluntary_ctxt_switches: 4