Using | pipe character from a $variable makes it treat as just another argument in bash; how to escape it?
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 eval
uate 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
Related videos on Youtube
laggingreflex
Updated on September 18, 2022Comments
-
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 tols
.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 over 9 yearsAnother option would be to define an alias:
alias ls='ls | sort -n'
-
Brian Stanley about 7 yearsCould 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 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!.