Как преобразовать вывод ps (1) в JSON?

Я хочу преобразовать вывод команды ps в JSON, чтобы обрабатывать ее как структурированные данные (с jq в данном конкретном случае). Как мне это сделать?

Результат выглядит следующим образом:

  PID TTY TIME CMD 20162 pts/2 00:00:00 ps 28280 pts/2 00:00:02 zsh 

Строка заголовка всегда присутствует.

3 Solutions collect form web for “Как преобразовать вывод ps (1) в JSON?”

Существует два очевидных способа представления вывода столбцов в JSON: как массив массивов и как массив объектов. В первом случае вы конвертируете каждую строку ввода в массив; в последнем, к объекту.

Команды, перечисленные ниже, работают как минимум с выходом procps-ng на Linux для команд ps и ps -l .

Вариант №1: массив массивов

Использование Perl

Вы можете преобразовать выходные данные с помощью Perl и модуля CPAN JSON :: XS .

 # ps | perl -MJSON -lane 'my @a = @F; push @data, \@a; END { print encode_json \@data }' [["PID","TTY","TIME","CMD"],["12921","pts/2","00:00:00","ps"],["12922","pts/2","00:00:00","perl"],["28280","pts/2","00:00:01","zsh"]] 

Используя jq

Кроме того, вы можете использовать jq для выполнения преобразования.

 # ps | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]]' [ [ "PID", "TTY", "TIME", "CMD" ], [ "16694", "pts/2", "00:00:00", "ps" ], [ "16695", "pts/2", "00:00:00", "jq" ], [ "28280", "pts/2", "00:00:02", "zsh" ] ] 

Вариант № 2: массив объектов

Вы можете преобразовать вход в массив объектов JSON со значимо названными ключами, взяв имена ключей из строки заголовка.

Это требует немного больших усилий и, в частности, немного сложнее в jq. Тем не менее, результат, вероятно, более удобочитаемый для человека.

Использование Perl

 # ps | perl -MJSON -lane 'if (!@keys) { @keys = @F } else { my %h = map {($keys[$_], $F[$_])} 0..$#keys; push @data, \%h } END { print encode_json \@data }' [{"TTY":"pts/2","CMD":"ps","TIME":"00:00:00","PID":"11030"},{"CMD":"perl","TIME":"00:00:00","PID":"11031","TTY":"pts/2"},{"TTY":"pts/2","CMD":"zsh","TIME":"00:00:01","PID":"28280"}] 

Обратите внимание, что ключи в произвольном порядке для каждой записи. Это артефакт о том, как работают хэши Perl.

Используя jq

 # ps | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]] | .[0] as $header | .[1:] | [.[] | [. as $x | range($header | length) | {"key": $header[.], "value": $x[.]}] | from_entries]' [ { "PID": "19978", "TTY": "pts/2", "TIME": "00:00:00", "CMD": "ps" }, { "PID": "19979", "TTY": "pts/2", "TIME": "00:00:00", "CMD": "jq" }, { "PID": "28280", "TTY": "pts/2", "TIME": "00:00:02", "CMD": "zsh" } ] 

Я бы предложил явно установить, что вы хотите, чтобы вывод ps был с опцией -o. Кроме того, используйте –no-header, если вы не хотите, чтобы заголовок в вашем json-выходе.

Я бы предложил в качестве отправной точки – не использовать ps а затем разобрать его. Это хороший способ причинить себе боль (например, вы хотите расширить его, чтобы включить аргументы командной строки, которые ограничены пробелами).

Таким простым было бы:

 #!/usr/bin/env perl use strict; use warnings; use JSON; use Proc::ProcessTable; my $json; foreach my $proc ( @{ Proc::ProcessTable -> new -> table } ) { push ( @$json, { %$proc } ); } print to_json ( $json, { pretty => 1 } ); 

Это даст вам полный список полей ps , которые могут быть излишними.

И если вы хотите сделать это одним лайнером:

 perl -MJSON -MProc::ProcessTable -e 'print to_json ( [ map { %$_ } } @{ Proc::ProcessTable->new->table } ], { pretty => 1 } );' 
  • Как показать время процессора для процессов через вершину без «корневых» процессов
  • Как просмотреть все процессы предков?
  • Как получить начальное время для несуществующего процесса в AIX?
  • Лучше / предпочтительнее убивать все дочерние процессы с помощью PPID или PGID?
  • Почему apache2 обнаруживает несуществующий список процессов?
  • процесс не использует новую конфигурацию открытого файла, которую я установил?
  • Пользователь Docker, выполняющий процесс, не может быть удален
  • ps переключает для отображения PID, PPID, PGID и SID в совокупности
  • В чем смысл этого тестового выражения ?
  • Подавить предупреждение от ps -aux на Linux
  • Убийство PGIDs, но proceses возрождаются, как я могу сделать это постоянным?
  • Linux и Unix - лучшая ОС в мире.