in reply to system call (backticks) with pipes

I am concern about using pipes in my system calls.

There's nothing special about pipes. There's something special about $, as they interpolate in backticks.

Since $3 is probably empty,

my $day = `/bin/date | awk 'BEGIN {FS=" "}{print $3}'`;
is the same as
my $day = `/bin/date | awk 'BEGIN {FS=" "}{print }'`;

Fix:

my $cmd = q{/bin/date | awk 'BEGIN {FS=" "}{print $3}'}; my $day = `$cmd`;

Replies are listed 'Best First'.
Re^2: system call (backticks) with pipes
by papai (Novice) on Jun 18, 2010 at 19:05 UTC
    Thank you for addressing my actual concern, you seemed to get my dilemma. It worked. Thank you.
Re^2: system call (backticks) with pipes
by Anonymous Monk on Nov 17, 2016 at 20:28 UTC

    What about a mixed case? I want variable substitution in part of the command.

    $boot_device = q awk 'FNR == 2 { print $1 }'; $boot_device = `$boot_device`; print "$boot_device\n"; $UUID_boot = q awk '{ print $2 }' | sed 's/"//g'; $UUID_boot = `$UUID_boot`; $print "$UUID_boot\n";

    I want $boot_device to be variable expanded but I don't want $2 to be expanded. Using q, the command is being sent as

    blkid $boot_device | awk '{ print $2 }' | sed 's/"//g'

    Using qq the command is being sent as

    blkid /dev/md126p1 | awk '{ print }' | sed 's/"//g'

    which results in an error.

      Then you want to selectively quote the variables using backslashes or construct your strings more carefully by joining them together from other parts:

      print "My two cents: \0.02\n"; my $cat = 'cat'; print "Some awk command: $cat | awk '{ print \$2 }'\n";

      But maybe you just want to use Perl instead of sed and awk? There are even converters that give you the rough Perl code you need for an awk program. See a2p.

      Judging by the unformatted, unreadable and as yet unreaped version of this post,
          $boot_device = q awk 'FNR == 2 { print $1 }';
      and similar are probably intended to be something like
          $boot_device = q[ awk 'FNR == 2 { print $1 }'];
      (and $print should be print).


      Give a man a fish:  <%-{-{-{-<

      I want variable substitution in part of the command.

      So just escape those dollars which you want to pass as literals.

      #!/usr/bin/env perl use strict; use warnings; use Test::More tests => 1; my $boot_device = '/dev/md126p1'; my $cmd = qq#blkid $boot_device | awk '{ print \$2 }' | sed 's/"//g'#; my $shouldbe = q#blkid /dev/md126p1 | awk '{ print $2 }' | sed 's/"//g +'#; is ($cmd, $shouldbe);

      And never pipe awk to sed - that would be pointless.