Search code examples
bashperlbackticks

how to escape the < <() idiom in perl


I have a system command which i am trying to execute, but it gives me error "Syntax error: redirection unexpected"

Trying command:

datamash -ft, -g 1 mean 3 mean 4 < <(tail -n +2 yourfile | sort -t, -k1,2) | cut -d, -f1,2,5,6 

I tried readpipe and also escaped the < < with \< \<, but doesn't work.

below command doesn't work ==>

`datamash -ft, -g 1 mean 3 mean 4 \< \<(tail -n +2 yourfile | sort -t, -k1,2) | cut -d, -f1,2,5,6`

Solution

  • Backticks aka readpipe expect a command passed to sh (or cmd in Windows). You appear to have a bash command rather than a sh command. Fixed:

    `bash -c 'datamash -ft, -g 1 mean 3 mean 4 < <(tail -n +2 yourfile | sort -t, -k1,2) | cut -d, -f1,2,5,6'`
    

    If you had vars to interpolate, it would look like

    use String::ShellQuote ( shell_quote );
    
    my $qfn = '...';
    my $tail_cmd = shell_quote('tail', '-n', '+2', $qfn);
    my $bash_cmd = "datamash -ft, -g 1 mean 3 mean 4 < <( $tail_cmd | sort -t, -k1,2 ) | cut -d, -f1,2,5,6";
    my $sh_cmd = shell_quote('bash', '-c', $bash_cmd);
    `$sh_cmd`
    

    As @chepner noticed, the bash command can be converted into a simpler command that's compatible with sh. This reduces the first snippet to the following:

    `tail -n +2 yourfile | sort -t, -k1,2 | datamash -ft, -g 1 mean 3 mean 4 | cut -d, -f1,2,5,6'`
    

    This doesn't help us get away from using shell_quote in the second snippet, but it does reduce it it the following:

    use String::ShellQuote ( shell_quote );
    
    my $qfn = '...';
    my $tail_cmd = shell_quote('tail', '-n', '+2', $qfn);
    my $sh_cmd = "$tail_cmd | sort -t, -k1,2 | datamash -ft, -g 1 mean 3 mean 4 | cut -d, -f1,2,5,6";
    `$sh_cmd`