我正在寻找一种可靠的方法来将完整的命令行参数传递给进程,即使这些参数是很长。
我确实了解ps -f -p <pid>
和/proc/<pid>/cmdline
,两者通常都能胜任这项工作。问题是,这两个似乎都将命令行参数截断为 4096 个字符,而且我知道这个参数更长(这是一个 java 应用程序,输出在类路径字符串的中间截断),并xargs --show-limits
告诉我我的系统允许最多 2094184 个参数长度。
有没有办法做到这一点?
更新:我能够通过制作一个包装器来获取完整的命令行参数字符串,该包装器是我之前放置在路径中的,并将参数记录到文件中,然后再使用相同的参数调用正确的二进制文件。
#!/bin/bash
file=/tmp/commandtrap-$$.log
/usr/bin/echo "$@" >$file
/usr/lib/jvm/java-7-openjdk/jre/bin/java "$@"
然而,这是一个丑陋的解决方法,只有在我可以停止并运行该过程时才有效。
理想情况下,应该有一种方法可以获得完整的命令,而无需关闭正在运行的进程(或以任何方式干扰它)
答案1
我认为一般情况下没有办法。可能存在针对特定操作系统的方法。您说的是 Unix/Linux,但也许您对特定操作系统的解决方案感兴趣?
例如,Solaris 将进程参数存储在两个位置。一种是内核中与进程关联的不可变缓冲区。但由于它是内核缓冲区,因此长度有限,并且它可能是命令行的截断版本。
另一个位置是进程本身中的 ARGV[]。可以查询(例如 via pargs
)并将返回未截断的内容。但由于 ARGV 是进程内存的一部分,因此可以随时修改。内容可能与启动该进程的命令行不同。
不能保证后来的用户找到原始命令行。
我刚刚在这里找到了 Stéphane Chazelas 对类似问题的回答:ps:完整命令太长
它似乎包含一个尝试在 x86 ELF 二进制文件上解码 ARGV[] 的方法,但我无法在测试用例中从中获取数据。我不知道为什么。但该技术似乎是合理的。