使用 | 来自 $variable 的管道字符使它被视为 bash 中的另一个参数;怎么逃呢?

lag*_*lex 9 shell bash pipe quoting variable

我有一个像这样的 bash 脚本

export pipedargument="| sort -n"
ls $pipedargument
Run Code Online (Sandbox Code Playgroud)

但它给出了错误

ls: |: No such file or directory
ls: sort: No such file or directory
Run Code Online (Sandbox Code Playgroud)

它似乎将 的内容"| sort -n"视为传递给 的参数ls

我怎样才能逃脱它以便它被视为常规的管道命令?

我正在尝试有条件地设置$pipedargument. 我想我可以有条件地执行不同版本的命令,但仍然想知道是否有办法使这项工作像上面一样?

Joh*_*024 10

你是对的,你不能用|那种方式。原因是shell在进行变量替换之前已经寻找了管道并将它们分成了命令。因此,|被视为另一个字符。

一种可能的解决方法是按字面意思放置管道字符:

$ cmd="sort -n"
$ ls | $cmd
Run Code Online (Sandbox Code Playgroud)

如果您不想要管道,则可以将其cat用作“nop”或占位符:

$ cmd=cat
$ ls | $cmd
Run Code Online (Sandbox Code Playgroud)

这种方法避免了eval微妙之处。另请参见此处

更好的方法:数组

更复杂的方法是使用bash数组代替普通字符串:

$ cmd=(sort -n)
$ ls | "${cmd[@]}"
Run Code Online (Sandbox Code Playgroud)

一旦您需要命令cmd包含带引号的参数,数组的优势就变得很重要。


jim*_*mij 5

您可以使用eval以下命令:

eval "ls $pipedargument"
Run Code Online (Sandbox Code Playgroud)

甚至更好地定义函数,如:

sorted() { "$@" | sort -n; }
Run Code Online (Sandbox Code Playgroud)

然后用所需的参数调用它:

sorted ls /tmp
Run Code Online (Sandbox Code Playgroud)