在Linux系统中,根据进程号获取进程的命令行参数。常规方法是读取/proc/{PID}/cmdline,用'\0'分隔里面的字符得到进程的args[],??例如下面的例子:#xxd/proc/7771/cmdline0000000:2f69746f612f6170702f6d6176652f62/itoa/app/mave/b0000010:696e2f6d617665002d7067.-p./itoa0000020:2f6170702f6d/mave66176/通过除0x00(C语言字符串终止符),可以解析出进程args[]:args[0]=/itoa/app/mave/bin/maveargs[1]=-pargs[2]=/itoa/app/mave但有时,我们会看到这样的进程cmdline:#xxd/proc/7276/cmdline00000000:6e67696e783a20776f726b6572207072nginx:workerpr00000010:6f6365737300000000.0000ocess0...0.....00000020:000000000000000000000000000000000000000000000000000000000000000000000000000000来62696e2f进程/usr/sbin/00000020:6e67696e78202d63202f6574632f6e67nginx-c/etc/ng00000030:696e782f6e67696e782e636f6e66inx/nginx.conf完全不走套路。看起来应该是0x00,但它使用了0x20(空格符),有时,最后会出现一堆0x00。"满意的结果。那么这里是怎么回事呢?原来cmdline中的内容其实就是进程main函数的参数args的内容。一般情况下,进程的args就是进程的启动参数.但是有些进程只是覆盖了args的内容.由于可以随意改变,所以会出现各种"自定义"参数形式,比如上面nginx的做法.因此,如果你尝试用0x00分割参数,是不可靠的对于一些特殊的进程。但是,由于ps程序显示的内容其实是cmdline中的东西,所以遇到0x00时,会显示为空格,后面连续的0x00会被忽略。因此,上面的nginx使用ps的示例将如下所示:root333410February23?00:00:00nginx:masterprocess/usr/sbin/nginx-c/etc/nginx/nginx.confroot727633340February26?00:00:01nginx:workerprocess按照ps的解构方法做起来不难。setproctitlePython有一个第三方库setproctitle,用于通过修改args来设置进程标题。为什么一件看似简单的事情需要专门的库来做呢?其实,这其中另有玄机。在Linux中,程序的参数存储空间紧跟在环境变量的存储位置之后:因此,过长的标题也会破坏环境变量environ的值。安全的做法是先把环境变量复制到其他地方,然后修改environ[x]的指向,再复制整个args[]。示例代码请参考nginx设置流程标题。更多关于cmdline的问题请参考:Howtoparse/proc/pid/cmdlineFindingthecommandforaspecificPIDinLinuxfromPython
