Using | pipe character from a $variable makes it treat as just another argument in bash; how to escape it?

11,358

Solution 1

You are right that you cannot use | that way. The reason is that the shell has already looked for pipelines and separated them into commands before it does the variable substitution. Hence, | is treated as just another character.

One possible work-around is to place the pipe character literally:

$ cmd="sort -n"
$ ls | $cmd

In the case that you don't want a pipeline, you can use cat as a "nop" or placeholder:

$ cmd=cat
$ ls | $cmd

This method avoids the subtleties of eval. See also here.

A better approach: arrays

A more sophisticated approach would use bash arrays in place of plain strings:

$ cmd=(sort -n)
$ ls | "${cmd[@]}"

The advantage of arrays becomes important as soon as you need the command cmd to contain quoted arguments.

Solution 2

You can evaluate the command:

eval "ls $pipedargument"

or even better define function like:

sorted() { "$@" | sort -n; }

and later on call it with desired arguments:

sorted ls /tmp
Share:
11,358

Related videos on Youtube

laggingreflex
Author by

laggingreflex

Updated on September 18, 2022

Comments

  • laggingreflex
    laggingreflex over 1 year

    I have a bash script like this

    export pipedargument="| sort -n"
    ls $pipedargument
    

    But it gives the error

    ls: |: No such file or directory
    ls: sort: No such file or directory
    

    It seems to be treating the contents of "| sort -n" as just an argument passed to ls.

    How can I escape it so that it's treated as a regular piped command?

    I'm trying to conditionally set the $pipedargument. I guess I could just conditionally execute different versions of the command but still wondering if there's a way to make this work like above?

  • thiagowfx
    thiagowfx over 9 years
    Another option would be to define an alias: alias ls='ls | sort -n'
  • Brian Stanley
    Brian Stanley about 7 years
    Could you clarify why arrays are needed in case of quoted arguments? I ran into that, but don't quite understand why it doesn't work.
  • John1024
    John1024 about 7 years
    @anxieux A short answer is that a quote, when inside a shell string, loses all its syntactical power to group words and is instead treated like just any other character. For a longer and excellent discussion of this issue, see: I'm trying to put a command in a variable, but the complex cases always fail!.