Использование правых Perl ссылок на массив с IP C :: Run - PullRequest
1 голос
/ 29 мая 2020

Я пытаюсь заставить этот Perl код работать правильно, и я считаю, что мне просто нужно правильно указать свои ссылки. Я был бы признателен за любые отзывы о том, как использовать ссылки, но если этот код не может работать без изменений API, я также был бы признателен за отзывы о том, как изменить окружающие API-интерфейсы для поддержки необходимых мне типов данных.

Я пытаюсь добавить новый тест в набор тестов PostgreSQL. Рассматриваемый код запускает подпроцесс и сохраняет аргументы процесса в литерале массива в ha sh. например:

my %pgdump_runs = (
    defaults => {
        dump_cmd => [
            'pg_dump', '--no-sync',
            '-f',      "$tempdir/defaults.sql",
            'postgres',
        ],
    },
    # and others
)

Этот массив передается вспомогательной библиотеке следующим образом:

    $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} },
        "$run: pg_dump runs");

Вспомогательная библиотека продолжает передавать массив вниз:

sub command_ok
{
    my ($cmd, $test_name) = @_;
    my $result = run_log($cmd);

а затем, наконец, вызов IP C :: Run :

sub run_log
{
    return IPC::Run::run(@_);
}

Чтобы написать мой тестовый пример, у меня есть , чтобы передать вывод команды в файл дескриптор, не поддерживающий поиск. Похоже, что модуль IP C :: Run поддерживает трубопровод для вас. Вот пример для документации:

run \@cmd1, '|', \@cmd2;

Но я пробовал несколько разных способов структурировать литерал массива, и ни один из них не помог. Например, я пробовал это и считаю, что это дало мне ошибку ARRAY(0xFFFFFFFF):

        dump_cmd => [
            ['pg_dump', 'db'],
            '|',
            ['pg_restore', 'db2'],
        ],

Как я могу получить этот код для настройки нескольких подпроцессов с конвейером?

ОБНОВЛЕНИЕ : Я попробовал предложение ikegami: функция command_ok может иметь только два аргумента, поэтому это не работает (вы должны передать ссылку на массив для первого аргумента).

UPDATE: поворот на IP C: Функция отладки Run Я вижу, как он пытается интерпретировать мою командную строку. Вместо того, чтобы разыменовать массив, он пытается преобразовать его в строку (?) И exe c эту строку как исполняемый файл:

1070 IPC::Run 0002 01234567890- [#11(59856)]: parsing [ 'ARRAY(0x7ff3016f1090)', '|', 'ARRAY(0x7ff3016f1510)', '>/Users/david/src/pg_bug/postgres/foo' ]

1 Ответ

1 голос
/ 29 мая 2020

Фактически вы делаете следующее: [1]

my %pgdump_runs = (
    foo => {
        dump_cmd => [
            ['pg_dump', 'db'],
            '|',
            ['pg_restore', 'db2'],
        ],
    },
);

IPC::Run::run( $pgdump_runs{foo}{dump_cmd} )

Это передает единственный аргумент в run, но вы указали, что хотите достичь чего-то аналогичного

run \@cmd1, '|', \@cmd2;

Для этого потребуется

IPC::Run::run( @{ $pgdump_runs{foo}{dump_cmd} } )

Несколько способов исправить это:

  1. Заменить

    return IPC::Run::run(@_);
    

    на

    return IPC::Run::run(@{ $_[0] });
    
  2. Заменить

    run_log($cmd);
    

    на

    run_log(@$cmd);
    
  3. Замените

    sub command_ok {
        my ($cmd, $test_name) = @_;
        my $result = run_log($cmd);
    }
    
    $node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} }, "$run: pg_dump runs");
    

    на

    sub command_ok {
        my $test_name = shift;
        my $result = run_log(@_);
    }
    
    $node->command_ok("$run: pg_dump runs", @{ $pgdump_runs{$run}{dump_cmd} });
    
  4. Замените

    dump_cmd => [
        ['pg_dump', 'db'],
        '|',
        ['pg_restore', 'db2'],
    ],
    

    на

    use String::ShellQuote qw( shell_quote );
    
    dump_cmd => join(' ',
        shell_quote('pg_dump', 'db'),
        '|',
        shell_quote('pg_restore', 'db2'),
    ),
    

Сноски:

  1. Если вы не пытаетесь автовивифицировать (а это не так),

    \@{ $pgdump_runs{$run}->{dump_cmd} }
    

    также можно записать как

    $pgdump_runs{$run}->{dump_cmd}
    

    И в обоих случаях -> можно опустить, потому что он находится между двумя индексами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...