[英]Using the right Perl array references with IPC::Run
我試圖讓這個 Perl 代碼正常工作,我相信我只需要正確地獲取我的參考。 我將不勝感激有關如何使用引用的任何反饋,但如果在沒有 API 更改的情況下無法使此代碼工作,我還將感謝有關如何更改周圍 API 以支持我需要的數據類型的反饋。
我正在嘗試向 PostgreSQL 測試套件添加一個新測試。 有問題的代碼運行一個子進程並將進程 arguments 存儲在 hash 中的數組文字中。 例如:
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);
然后最后調用IPC::Run :
sub run_log
{
return IPC::Run::run(@_);
}
要編寫我的測試用例,我必須將 pipe 和 output 的命令發送到不支持查找的文件描述符。 看起來 IPC::Run 模塊為您支持管道。 這是文檔的示例:
run \@cmd1, '|', \@cmd2;
但是我嘗試了很多不同的方法來嘗試構造我的數組文字,但都沒有奏效。 例如,我試過這個,我相信它給了我一個ARRAY(0xFFFFFFFF)
錯誤:
dump_cmd => [
['pg_dump', 'db'],
'|',
['pg_restore', 'db2'],
],
如何獲取此代碼以使用管道設置多個子流程?
更新:我嘗試了 ikegami 的建議: command_ok
function 只能有兩個 arguments 傳遞給它,所以這不起作用(你必須為第一個參數傳遞一個數組引用)。
更新:打開 IPC:Run 的調試功能我可以看到它是如何試圖解釋我的命令行的。 它不是取消對數組的引用,而是嘗試將其字符串化(?)並將該字符串作為可執行文件執行:
1070 IPC::Run 0002 01234567890- [#11(59856)]: parsing [ 'ARRAY(0x7ff3016f1090)', '|', 'ARRAY(0x7ff3016f1510)', '>/Users/david/src/pg_bug/postgres/foo' ]
您正在有效地執行以下操作: [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} } )
有幾種方法可以解決這個問題:
代替
return IPC::Run::run(@_);
和
return IPC::Run::run(@{ $_[0] });
代替
run_log($cmd);
和
run_log(@$cmd);
代替
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} });
代替
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'), ),
腳注:
除非你試圖自動激活(你不是),
\@{ $pgdump_runs{$run}->{dump_cmd} }
也可以寫成
$pgdump_runs{$run}->{dump_cmd}
在這兩種情況下, ->
都可以省略,因為它位於兩個索引之間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.