Bash中的条件流水线

4
我有一个筛选器,我希望能够选择性地启用它,我想知道如何在bash中以一种简洁的方式实现这一点。
FILTER="| sort" # also can be empty
ls $FILTER | cat

这段代码不能正常工作,因为它会以 |sort 作为参数来调用 ls 命令。

我该如何正确执行?请注意,我想避免创建 if 块以便保持代码易于维护(我的管道链比这个示例复杂得多)。


这些过滤器会接收任何类型的参数吗? - sobolevn
一种危险的生活方式是使用eval。如果您完全控制要评估的字符串,那么这可能是安全的;如果用户可以向要评估的字符串提供输入,则会出现灾难。他们可能说cat,但实际上传递的却是 cat; mv $HOME/.profile $HOME/.junk或者更糟糕(而且可能是不可逆转的,或者至少是难以逆转的)。因此,使用eval是危险的。然而,它确实存在,并且可以很有用。 - Jonathan Leffler
2个回答

4

您所考虑的方法不可行,因为变量扩展发生在语法解析之后。

您可以尝试以下方法:

foo_cmd | if [ "$order" = "desc" ] ; then
    sort -r
else
    sort
fi | if [ "$cut" = "on" ] ; then
    cut -f1
else
    cat
fi

0

您可以创建命令并在不同的 shell 中执行它。

FILTER="| sort" # create your filter here
# ls $FILTER | cat  <-- this won't work
bash -c "ls $FILTER | cat"

# or create the entire command and execute (which, i think, is more clean)
cmd="ls $FILTER | cat"
bash -c "$cmd"

如果您选择这种方法,您必须确保命令在语法上是有效的,并且确切地执行您的意图,而不是做出灾难性的事情。

这将带来所有动态代码执行的缺点,应该避免使用。 - hek2mgl
@hek2mgl 我同意,但据我所知,OP正试图通过应用在变量中定义的过滤器来做完全相同的事情,同时不愿使用条件结构。他必须通过其他方式确保命令是有效的。 - Anubis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接