Showing entries with tag "capture".

Found 3 entries

PHP: Run a command and capture STDOUT and STDERR separately

I need to run a shell command in PHP and capture STDOUT and STDERR separately. This function lets you run a command and returns a hash with the various components and outputs.

function run_cmd($cmd) {
    $start   = hrtime(true);
    $cmd     = escapeshellcmd($cmd);
    $process = proc_open($cmd, [
        1 => ['pipe', 'w'], // STDOUT
        2 => ['pipe', 'w'], // STDERR
    ], $pipes);

    if (!is_resource($process)) { return []; }

    $stdout = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[2]);
    $exit   = proc_close($process);

    $ret = [
        'exit_code' => $exit,
        'stdout'    => trim($stdout),
        'stderr'    => trim($stderr),
        'cmd'       => $cmd,
        'exec_ms'   => (hrtime(true) - $start) / 1000000,
    ];

    return $ret;
}
Leave A Reply

Perl: Array of all regexp captures

Perl v5.25.7 added support for the @{^CAPTURE} variable which wrapped all the regexp parenthesis captures up into an array. If you need this functionality in an older version of Perl you can use this function:

my $str =  "Hello Jason Doolis";
$str    =~ /Hello (\w+) (\w+)/;

my @captures = get_captures(); # ("Jason", "Doolis")
sub get_captures {
    no strict 'refs';

    my $last_idx = scalar(@-) - 1;
    my @arr      = 1 .. $last_idx;
    my @ret      = map { $$_; } @arr;

    return @ret;
}
Leave A Reply

Perl: Named captures in regexps

In a regular expression you can capture strings into variables using the default syntax:

$str = "2020-05-20";
$str =~ m/(\d{4})-(\d{2})-(\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $1, $2, $3);

In a more complex regular expression/string things may move around. In this case it's better to use named captures instead of numeric captures. This can be done by using the (?<name>) syntax. This will capture that parenthesis pair in to the hash %+ with the name specified.

$str = "2020-05-20";
$str =~ m/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

printf("Year: %s Month: %s Day: %s\n", $+{year},$+{month},$+{day});

Using named captures you can easily update your regular expression if the position of elements in your string change.

Note: If you use named captures, Perl also populates the numeric equivalent.

Leave A Reply