추신 : 전체 명령이 너무 깁니다


26

좋은 날!

'ps'를 사용하여 프로세스를 시작하는 명령을 봅니다. 문제는 명령이 너무 길고 'ps'가 완전히 표시하지 않는다는 것입니다.

예 : 'ps -p 2755 | less '및 다음 출력

  PID TTY      STAT   TIME COMMAND
2755 ?        Sl   305:05 /usr/java/jdk1.6.0_37/bin/java -Xms64m -Xmx512m -Dflume.monitoring.type=GANGLIA -Dflume.monitoring.hosts=prod.hostname.ru:8649 -cp /etc/flume-ng/conf/acrs-event:/usr/lib/flume-ng/lib/*:/etc/hadoop/conf:/usr/lib/hadoop/lib/activation-1.1.jar:/usr/lib/hadoop/lib/asm-3.2.jar:/usr/lib/hadoop/lib/avro-1.7.4.jar:/usr/lib/hadoop/lib/commons-beanutils-1.7.0.jar:/usr/lib/hadoop/lib/commons-beanutils-core-1.8.0.jar:/usr/lib/hadoop/lib/commons-cli-1.2.jar:/usr/lib/hadoop/lib/commons-codec-1.4.jar:/usr/lib/hadoop/lib/commons-collections-3.2.1.jar:/usr/lib/hadoop/lib/commons-compress-1.4.1.jar:/usr/lib/hadoop/lib/commons-configuration-1.6.jar:/usr/lib/hadoop/lib/commons-digester-1.8.jar:/usr/lib/hadoop/lib/commons-el-1.0.jar:/usr/lib/hadoop/lib/commons-httpclient-3.1.jar:/usr/lib/hadoop/lib/commons-io-2.1.jar:/usr/lib/hadoop/lib/commons-lang-2.5.jar:/usr/lib/hadoop/lib/commons-logging-1.1.1.jar:/usr/lib/hadoop/lib/commons-math-2.1.jar:/usr/lib/hadoop/lib/commons-net-3.1.jar:/usr/lib/hadoop/lib/guava-11.0.2.jar:/usr/lib/hadoop/lib/jackson-core-asl-1.8.8.jar:/usr/lib/hadoop/lib/jackson-jaxrs-1.8.8.jar:/usr/lib/hadoop/lib/jackson-mapper-asl-1.8.8.jar:/usr/lib/hadoop/lib/jackson-xc-1.8.8.jar:/usr/lib/hadoop/lib/jasper-compiler-5.5.23.jar:/usr/lib/hadoop/lib/jasper-runtime-5.5.23.jar:/usr/lib/hadoop/lib/jaxb-api-2.2.2.jar:/usr/lib/hadoop/lib/jaxb-impl-2.2.3-1.jar:/usr/lib/hadoop/lib/jersey-core-1.8.jar:/usr/lib/hadoop/lib/jersey-json-1.8.jar:/usr/lib/hadoop/lib/jersey-server-1.8.jar:/usr/lib/hadoop/lib/jets3t-0.6.1.jar:/usr/lib/hadoop/lib/jettison-1.1.jar:/usr/lib/hadoop/lib/jetty-6.1.26.cloudera.2.jar:/usr/lib/hadoop/lib/jetty-util-6.1.26.cloudera.2.jar:/usr/lib/hadoop/lib/jline-0.9.94.jar:/usr/lib/hadoop/lib/jsch-0.1.42.jar:/usr/lib/hadoop/lib/jsp-api-2.1.jar:/usr/lib/hadoop/lib/jsr305-1.3.9.jar:/usr/lib/hadoop/lib/junit-4.8.2.jar:/usr/lib/hadoop/lib/kfs-0.3.jar:/usr/lib/hadoop/lib/log4j-1.2.17.jar:/usr/lib/hadoop/lib/mockito-all-1.8.5.jar:/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/paranamer-2.3.jar:/usr/lib/hadoop/lib/protobuf-java-2.4.0a.jar:/usr/lib/hadoop/lib/servlet-api-2.5.jar:/usr/lib/hadoop/lib/snappy-java-1.0.4.1.jar:/usr/lib/hadoop/lib/stax-api-1.0.1.jar:/usr/lib/hadoop/lib/xmlenc-0.52.jar:/usr/lib/hadoop/lib/xz-1.0.jar:/usr/lib/hadoop/lib/zookeeper-3.4.5-cdh4.3.0.jar:/usr/lib/hadoop/.//bin:/usr/lib/hadoop/.//cloudera:/usr/lib/hadoop/.//etc:/usr/lib/hadoop/.//hadoop-annotations-2.0.0-cdh4.3.0.jar:/usr/lib/hadoop/.//hadoop-annotations.jar:/usr/lib/hadoop/.//hadoop-auth-2.0.0-cdh4.3.0.jar:/usr/lib/hadoop/.//hadoop-auth.jar:/usr/lib/hadoop/.//hadoop-common-2.0.0-cdh4.3.0.jar:/usr/lib/hadoop/.//hadoop-common-2.0.0-cdh4.3.0-tests.jar:/usr/lib/hadoop/.//hadoop-common.jar:/usr/lib/hadoop/.//lib:/usr/lib/hadoop/.//libexec:/usr/lib/hadoop/.//sbin:/usr/lib/hadoop-hdfs/./:/usr/lib/hadoop-hdfs/lib/asm-3.2.jar:/usr/lib/hadoop-hdfs/lib/commons-cli-1.2.jar:/usr/lib/hadoop-hdfs/lib/commons-codec-1.4.jar:/usr/lib/hadoop-hdfs/lib/commons-daemon-1.0.3.jar:/usr/lib/hadoop-hdfs/lib/commons-el-1.0.jar:/usr/lib/hadoop-hdfs/lib/commons-io-2.1.jar:/usr/lib/hadoop-hdfs/lib/commons-lang-2.5.jar:/usr/lib/hadoop-hdfs/lib/commons-logging-1.1.1.jar:/usr/lib/hadoop-hdfs/lib/guava-11.0.2.jar:/usr/lib/hadoop-hdfs/lib/jackson-core-asl-1.8.8.jar:/usr/lib/hadoop-hdfs/lib/jackson-mapper-asl-1.8.8.jar:/usr/lib/hadoop-hdfs/lib/jasper-runtime-5.5.23.jar:/usr/lib/hadoop-hdfs/lib/jersey-core-1.8.jar:/usr/lib/hadoop-hdfs/lib/jersey-server-1.8.jar:/usr/lib/hadoop-hdfs/lib/jetty-6.1.26.cloudera.2.jar:/usr/lib/hadoop-hdfs/lib/jetty-util-6.1.26.cloudera.2.jar:/usr/lib/hadoop-hdfs/lib/jline-0.9.94.jar:/usr/lib/hadoop-hdfs/lib/jsp-api-2.1.jar:/usr/lib/hadoop-hdfs/lib/jsr305-1.3.9.jar:/usr/lib/hadoop-hdfs/lib/log4j-1.2.17.jar:/usr/lib/hadoop-hdfs/lib/protobuf-java-2.4.0a.jar:/usr/lib/hadoop-hdfs/lib/servlet-api-2.5.jar:/usr/lib/hadoop-hdfs/lib/xmlenc-0.52.jar:/usr/lib/hadoop-hdfs/lib/zookeeper-3.4.5-cdh4.3.0.jar:/usr/lib/hadoop-hdfs/.//bin:/usr/lib/hadoop-hdfs/.//cloudera:/usr/lib/hadoop-hdfs/.//hadoop-hdfs-2.0.0-cdh4.3.0.jar:/usr/lib/hadoop-hdfs/.//hadoop-hdfs-2.0.

따라서 명령 행이 너무 길어 명령이 중간 구문을 중지합니다. 전체를 어떻게 볼 수 있습니까?

답변:


38

Linux에서 psfrom procps(-ng):

ps -fwwp 2755

4.2 이전의 Linux 버전에서는 여전히 커널 ( /proc/2755/cmdline)에서 4k 까지 제한되어 있으며 프로세스에게 요청하거나 디버거를 사용하도록 요청하는 것 외에는 더 많은 것을 얻을 수 없습니다.

$ sh -c 'sleep 1000' $(seq 4000) &
[1] 31149
$ gdb -p $! /bin/sh
[...]
Attaching to program: /bin/dash, process 31149
[...]
(gdb) bt
#0  0x00007f40d11f40aa in wait4 () at ../sysdeps/unix/syscall-template.S:81
[...]
#7  0x00007f40d115c995 in __libc_start_main (main=0x4022c0, argc=4003, ubp_av=0x7fff5b9f5a88, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff5b9f5a78)
at libc-start.c:260
#8  0x00000000004024a5 in ?? ()
#9  0x00007fff5b9f5a78 in ?? ()
#10 0x0000000000000000 in ?? ()
(gdb) frame 7
#7  0x00007f40d115c995 in __libc_start_main (main=0x4022c0, argc=4003, ubp_av=0x7fff5b9f5a88, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff5b9f5a78)
at libc-start.c:260
(gdb) x/4003s *ubp_av
0x7fff5b9ff83e: "sh"
0x7fff5b9ff841: "-c"
0x7fff5b9ff844: "sleep 1000"
0x7fff5b9ff84f: "1"
0x7fff5b9ff851: "2"
[...]
0x7fff5ba04212: "3999"
0x7fff5ba04217: "4000"

최대 5000 자까지 4 번째 인수를 인쇄하려면

(gdb) set print elements 5000
(gdb) p ubp_av[3]

방해하지 않는 것을 원하면 정보를 얻으려고 시도 할 수 있습니다.이 값이 0으로 설정되어 있지 않은 /proc/2755/mem경우에는 kernel.yama.ptrace_scope수퍼 유저 권한이 필요합니다. 아래의 내용은 저에게 효과적입니다 (모든 인수와 환경 변수를 인쇄합니다).

$ perl -e '$p=shift;open MAPS, "/proc/$p/maps";
          ($m)=grep /\[stack\]/, <MAPS>;
          ($a,$b)=map hex, $m =~ /[\da-f]+/g;
          open MEM, "/proc/$p/mem" or die "open mem: $!";
          seek MEM,$a,0; read MEM, $c,$b-$a;
          print((split /\0{2,}/,$c)[-1])' "$!" | tr \\0 \\n | head
sh
-c
sleep 1000
1
2
3
4
5
6
7

( "$!"프로세스 ID로 교체 ). 위의 사용 리눅스 풋 문자열이가 가리키는 사실 argv[], envp[]프로세스의 스택의 맨 아래에있는 실행 파일 이름.

위의 스택에서 두 개 이상의 연속적인 NUL 바이트의 두 세트 사이에서 맨 아래 문자열을 찾습니다. 인수 또는 env 문자열이 비어 있으면 작동하지 않습니다. argv 또는 envp 중간에 2 NUL 바이트의 시퀀스가 ​​있기 때문입니다. 또한 우리는 argv 문자열이 어디서 멈추고 envp 문자열이 어디서 시작하는지 알지 못합니다.

그 해결 방법은 argv[](포인터) 의 실제 내용을 거꾸로 보면서 휴리스틱을 개선하는 것 입니다. 아래는 ELF 실행 파일을위한 i386 및 amd64 아키텍처에서 작동합니다.

perl -le '$p=shift;open MAPS, "/proc/$p/maps";
      ($m)=grep /\[stack\]/, <MAPS>;
      ($a,$b)=map hex, $m =~ /[\da-f]+/g;
      open MEM, "/proc/$p/mem" or die "open mem: $!";
      seek MEM,$a,0; read MEM, $c,$b-$a;
      $c =~ /.*\0\0\K[^\0].*\0[^\0]*$/s;
      @a=unpack"L!*",substr$c,0,$-[0];
      for ($i = $#a; $i >=0 && $a[$i] != $a+$-[0];$i--) {}
      for ($i--; $i >= 0 && ($a[$i]>$a || $a[$i]==0); $i--) {}
      $argc=$a[$i++];
      print for unpack"(Z*)$argc",substr$c,$a[$i]-$a;' "$!"

기본적으로, 상기와 같은 않지만, 그것은의 첫 번째 문자열 발견되면 argv[](의 또는 적어도 하나 argv[]또는 envp[]문자열 빈 상자가있는 경우)를이 스택의 상단의 나머지에 뒤로 보이는, 그래서 그것은, 해당 주소를 알고 같은 값을 가지는 포인터 그런 다음 포인터가 될 수없는 숫자를 찾을 때까지 거꾸로 계속 argc봅니다. 다음 정수는 argv[0]입니다. 그리고 알고 argv[0]하고 argc, 그것은 인수 목록을 표시 할 수 있습니다.

프로세스가 argv[]일부 NUL 분리 문자를 대체 할 가능성이 있거나 argc0 인 경우 ( argc일반적으로 적어도 1을 포함하는 경우 argv[0]) 작동하지 않지만 ELF 실행 파일의 경우에는 일반적으로 작동해야합니다.

4.2 이상에서는 /proc/<pid>/cmdline더 이상 잘리지 않지만 ps최대 디스플레이 너비는 128K입니다.


디버거에 대해 더 자세히 말씀해 주시겠습니까? 실행중인 프로세스에 어떻게 첨부합니까?
V. Artyukhov

1
@ V.Artyukhov 나는 그것이하는 일이라고 생각합니다 -p $!( $!가장 최근에 시작된 프로세스의 PID입니다. 백그라운드이기 때문에 gdb가 호출 될 때 여전히 실행됩니다).
CVn September

예, 더 긴 명령으로 긴 명령과 싸우십시오. 좋은 설명과 문서로 답을 얻으려면 농담을 제쳐두고 +1하십시오.
Stan Strum

12

하나 또는 두 개의 -w플래그를 추가하십시오 . 출력이 더 넓어집니다. 예 ps auxww.


5

Linux 커널 4.2 이상에서는 /proc/<pid>/cmdline더 이상 잘리지 않으며 다음이 잘 작동합니다.

xargs -0 printf '%s\n' < /proc/2755/cmdline
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.