PS: полная команда является слишком длинной

Необходимо использовать --no-collapse опция, вместо --tab-correct, и вставьте литеральные вкладки в свою строку, например, с

"star "$'\t'" end" 

или использование Ctrl-v и нажатие клавиши Tab.

26
21.09.2013, 00:54
2 ответа

На Linux, с ps от procps(-ng):

ps -fwwp 2755

В версиях Linux до 4,2, это все еще ограничено хотя (ядром (/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"

Распечатать 4-й аргумент максимум с 5 000 символов:

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

Если Вы хотите что-то ненавязчивое, Вы могли бы попытаться получить информацию от /proc/2755/mem (отметьте это если kernel.yama.ptrace_scope не установлен на 0, Вам будут нужны полномочия суперпользователя для этого). Это ниже работ для меня (печатает все аргументы и переменные среды), но нет большой гарантии, я думал бы (ошибка, и неожиданную входную обработку оставляют как осуществление читателю):

$ 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

(замена "$!" с идентификатором процесса). Вышеупомянутое использование то, что Linux помещает строки, которыми указывают argv[], envp[] и выполняемое имя файла у основания стопки процесса.

Вышеупомянутые взгляды в том стеке для самой нижней строки промежуточные два набора двух или больше последовательных байтов NUL. Это не работает, если какой-либо из аргументов или огибающих строк пуст, потому что затем у Вас будет последовательность 2 байтов NUL посреди тех argv или envp. Кроме того, мы не знаем, где argv представляет остановку в виде строки и где envp запускаются.

Работа вокруг для этого должна была бы совершенствовать ту эвристику путем искания назад фактического содержания argv[] (указатели). Это ниже работ над i386 и amd64 архитектурой для исполняемых файлов ELF, по крайней мере:

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 или если argc 0 (argc обычно по крайней мере 1 для включения argv[0]) но должен работать в общем случае, по крайней мере, для исполняемых файлов ELF.

В 4,2 и более новый, /proc/<pid>/cmdline больше не является усеченным, но ps самостоятельно имеет максимальную ширину дисплея 128K.

38
27.01.2020, 19:39
  • 1
    Вы могли сказать больше об отладчике? Как я могу присоединить его к рабочему процессу? –  V. Artyukhov 20.09.2013, 14:00
  • 2
    @V.Artyukhov, я предполагаю, что это что -p $! делает ($! PID последний раз запущенного процесса, который, так как это - фон, будет все еще работать, когда gdb будет вызван). –  a CVn 20.09.2013, 14:14
  • 3
    Да, боритесь с долгими командами с еще более длительными командами. Шутки в стороне, +1 для ответа с хорошим объяснением и документации. –  Stan Strum 12.02.2018, 20:28

Добавьте один или два -w флаги. Это делает вывод шире. например. ps auxww.

12
27.01.2020, 19:39

Теги

Похожие вопросы