Custom separator in ps
问题描述
我在一个过时的Debian 10系统中的bash脚本中使用了以下命令:
这个命令工作正常,输出格式如下:
1
2
3
4
|
10161 ;;; [kworker/0:1-cgroup_destroy]
12173 ;;; [kworker/2:0-events]
12379 ;;; [kworker/u8:0-events_unbound]
12464 ;;; [kworker/u8:1-flush-254:2]
|
自定义分隔符;;;在进程ID和进程名称之间,这正是我想要的!
现在我将系统升级到当前的Debian 13,这个功能不再工作了。如果没有自定义分隔符,命令仍然正常工作:
输出:
1
2
3
|
4180 [kworker/0:1-ata_sff]
4181 [kworker/3:1-ata_sff]
4292 [kworker/2:2-ata_sff]
|
但是使用自定义分隔符时:
出现错误:
1
|
Error: must set personality to get -x option
|
我不知道从Debian 10到13的升级过程中什么时候这个功能被破坏了。有任何想法如何恢复我的自定义分隔符功能吗?
版本信息:
1
2
|
ps -V
ps from procps-ng 4.0.4
|
技术解答
答案1
文档表明这个功能本来不应该工作,这种看法也被广泛认同,所以在版本4.0.3中这个功能的丢失没有引起太多反应(行为变化是由于对%cpu处理的一个晦涩且不完整的修复)。然而,实际上"AIX自由格式"确实应该工作,最近已经恢复了;不幸的是,修复只在procps的4.0.5版本中可用,这个版本在Debian中还没有提供,更不用说在Debian 13中了。
我不知道在您当前情况下使用Debian 13中的ps版本有什么解决方法;您可以构建更新版本的ps,也许可以在Debian中提交一个问题指向上游修复。这不太可能符合稳定版修复的条件;我认为在Debian本身中最好的希望是等待4.0.5进入测试版后进行回溯。
您当然可以在某处保留Debian 10或更好的11版本的ps并使用它;如果您手头没有,可以按以下方式下载并提取(在amd64上):
1
2
3
|
$ wget http://deb.debian.org/debian/pool/main/p/procps/libprocps8_3.3.17-5_amd64.deb http://deb.debian.org/debian/pool/main/p/procps/procps_3.3.17-5_amd64.deb
$ sudo apt install ./libprocps8_3.3.17-5_amd64.deb
$ dpkg-deb -x procps_3.3.17-5_amd64.deb myps
|
将myps/bin/ps复制到PATH上的其他地方,重命名为myps,然后您就可以运行:
1
|
$ myps -axo "%p ;;; %a"
|
并获得您期望的结果。ps中偶尔会发现漏洞,所以依赖一个非常旧的版本进行常规使用可能不是一个好主意。
答案2
一个完整的可用解决方法,使用Docker容器来提供特定版本的procps,这里是4.0.5(来自Stephen Kitt答案的最新工作版本),而不会弄乱apt和您的系统(通过设计隔离):
4.0.5版本的库要求/依赖:
1
2
3
4
5
6
7
8
|
$ ldd /usr/bin/ps
linux-vdso.so.1 (0x00007fff88d94000)
libproc2.so.1 => /lib64/libproc2.so.1 (0x00007f8bfa136000)
libc.so.6 => /lib64/libc.so.6 (0x00007f8bf9f3c000)
libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f8bf9e28000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8bfa1b4000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f8bf9e1a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f8bf9d32000)
|
在终端中复制/粘贴的解决方案:
先决条件(这里以Debian为例)
1
2
|
# apt install docker.io
# systemctl enable --now docker.service
|
安装/配置:
1
2
3
4
5
6
|
cat>Dockerfile<<EOF
FROM opensuse/leap:16.0
RUN zypper -n refresh && zypper -n install procps
ENTRYPOINT ["ps"]
EOF
docker build -t ps:latest .
|
使用:
1
2
3
4
5
6
|
docker run \
--rm \
--pid=host \
-v /etc:/host-etc:ro \
-v /proc:/host-proc:ro \
ps -axo "%p ;;; %a"
|
完成了…
如果您需要简化这个长命令,甚至可以创建一个shell别名。
注意:
这不特定于procps,当您需要在受限/私有网络(我指的是不暴露给整个互联网的服务)中使用特定版本的应用程序(甚至是过时的,如PhpLdapAdmin)时,这是您的最佳选择。