Как поменять местами два поля внутри файла JSON

Из chown(2) man page:

Только привилегированный процесс (Linux: процесс с CAP_CHOWN) может изменить владельца файла. Владелец файла может изменить группу файла на любую группу, членом которой является владелец. A привилегированный процесс (Linux: с CAP_CHOWN) может изменить группу произвольно.

Ваш процесс не является ни привилегированным, ни изменяющим группу файла, которым он владеет, на группу, в которой состоит его владелец.

Поэтому вам необходимо получить соответствующие привилегии. Два самых простых способа сделать это -

  1. Написать минимальную двоичную программу (возможно, на C) для установки права собственности на этот файл (я предполагаю, что имя пути файла может быть жестко закодировано, чтобы предотвратить злоупотребления) и заставить ее установить user-id на root, или даже лучше, добавить CAP_CHOWN возможность с помощью sudo setcap cap_chown+ep <имя_программы>, что не заставит программу запускаться от имени root со всеми вытекающими последствиями.

  2. Напишите подходящую запись в /etc/sudoers, чтобы разрешить выполнение этой конкретной команды с помощью sudo без пароля: напишите строку типа

    bar ALL = (root) NOPASSWD: /bin/chown foo:server '/full/path/to/file'
    

    в файл в /etc/sudoers.d (и проверьте, что в /etc/sudoers есть соответствующая директива #includedir - в большинстве дистрибутивов Linux она есть). Убедитесь, что команда, вызываемая вашим скриптом, точно совпадает!

0
10.10.2018, 17:53
2 ответа

Я бы посоветовал избегать разбора данных JSON с помощью текстовых инструментов, таких как awkили sedи т. д.

Вместо этого используйте синтаксический анализатор JSON или язык, основанный на библиотеке JSON, например perl, pythonи т. д.

Вот пример сjq:

<file jq '.[] |= (.[2] as $t |.[2] =.[1] |.[1] = $t)'

Все объекты заменяются перестановкой 3-го и 2-го элемента массива. Обратите внимание, что массивы в jqначинаются с индекса 0.

5
28.01.2020, 02:16

Более подробным, чем jq, было бы использование языка сценариев с доступными библиотеками JSON:

ruby -rjson -e '
    data = JSON.parse File.read ARGV.shift
    data.transform_values! {|v| v[1], v[2] = v[2], v[1]; v}
    puts JSON.pretty_generate data
' file.json
perl -E '
    use Path::Tiny;
    use JSON;
    $json = JSON->new->utf8;
    $data = $json->decode( path(shift)->slurp_utf8 );
    while (($key, $val) = each %$data) {
        ($val->[1], $val->[2]) = ($val->[2], $val->[1]);
        $data->{$key} = $val;
    } 
    $json->canonical->indent;
    say $json->encode($data);
' file.json
1
28.01.2020, 02:16

Теги

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