testing_account has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks!

i need an help for this small part of code:

$NF = '$NF'; @elf_files = system("ls"); #or backtiks my $scraped_elfs = system("readelf -sW $elf_files[7] | awk '{print $NF +}'");
but it returns:
sh: unexpected "|"
thanks.

Replies are listed 'Best First'.
Re: system call error
by marto (Cardinal) on Apr 11, 2020 at 12:57 UTC
    my @elf_files = system("ls"); #or backtiks

    Your code doesn't do what you think it does. See Why can't I get the output of a command with system()?. Tutorials->Getting Started with Perl/Basic debugging checklist. Basic debugging could have simply been printing the values before you used them. In the chatterbox Corion provided you with a solution reporting the command actually being run on failure.

    Adding:

    use strict; use warnings;

    generates:

    Use of uninitialized value in concatenation (.) or string at ./derp.pl + line 8. readelf: Warning: Nothing to do.

    Rather than just:

    readelf: Warning: Nothing to do.

    You code doesn't cater for all use cases, e.g. if there's a sub directory:

    readelf: Error: 'ffmpeg_sources' is not an ordinary file

    You should consider not shelling out and just using perl to handle this, opendir, readdir, grep, or modules like Path::Tiny which provide simpler ways of doing this.

    Update: for completeness, the only line of code offered in the chatterbox was:

    system("readelf -sW $var | awk '{print \$NF}'");
Re: system call error
by hippo (Archbishop) on Apr 11, 2020 at 12:56 UTC
    1. Print out the value of $elf_files[7] to determine if it has what you expect (See Basic Debugging Checklist)
    2. Consider some form of glob rather than shelling out to ls
    3. Consider extracting the last field in the line within Perl instead of piping to awk. That will remove the need for $NF = '$NF'; or equivalents.
Re: system call error
by haukex (Archbishop) on Apr 11, 2020 at 19:52 UTC

    This is definitely one of those cases where all of the advice from here and here applies: First, don't do things like ls and awk in the shell, do them in Perl. For example, instead of ls, the module Path::Class is very nice. And for calling the readelf command, you should use one of the modules I suggest in the first link - such as IPC::System::Simple's capturex, or, if you also need to capture the command's STDERR, maybe IPC::Run3. There is example code for both in the first link.