Linux |grep:can';t打开| grep:can';t打开grep

Linux |grep:can';t打开| grep:can';t打开grep,linux,bash,Linux,Bash,给出输出: grep:无法打开| 格雷普:无法打开格雷普 格雷普:打不开-v grep:无法打开PROD\u OPL 格雷普:打不开| 格雷普:无法打开格雷普 格雷普:打不开-v grep:无法打开PROD\u OPL 我怎样才能解决这个问题$FILTER需要是动态的。我认为出现许多错误是因为bash无法将|解释为管道,因为它只是过滤器中的一个字符。因此,您需要实际将$FILTER作为表达式进行计算。例如,试试看 FILTER="grep -w PROD | grep -v PROD_OPL"

给出输出:

grep:无法打开|
格雷普:无法打开格雷普
格雷普:打不开-v
grep:无法打开PROD\u OPL
格雷普:打不开|
格雷普:无法打开格雷普
格雷普:打不开-v
grep:无法打开PROD\u OPL

我怎样才能解决这个问题<代码>$FILTER需要是动态的。

我认为出现许多错误是因为bash无法将
|
解释为管道,因为它只是
过滤器中的一个字符。因此,您需要实际将
$FILTER
作为表达式进行计算。例如,试试看

FILTER="grep -w PROD | grep -v PROD_OPL"

if (/usr/ucb/ps auxww | grep $1/$2 | $FILTER > /dev/null)
then
  #do something
fi
编辑 正如在各种评论中明确指出的那样:这很可能不是解决问题的方法。将字符串作为代码执行是不好的,而且可能是危险的设计。
这就是说,如果您完全控制了
过滤器的内容,那么这将是一个非常简单的黑客攻击。

要存储命令供以后使用,您需要使用一个函数

下面是一个基本示例,它将执行两个特定的
grep
命令:

FILTER="grep -w PROD | grep -v PROD_OPL"

if /usr/ucb/ps auxww | grep $1/$2 | eval "$FILTER" > /dev/null
then
  #do something
fi
grep$1/$2
的输出通过管道传输到函数的输入,函数的输入将其传递到管道,管道的输出将传递到函数的输出

函数的返回代码隐式保留为其最后一个命令之一,因此只有当筛选器匹配某些行时,
if
条件才会为真

就动态而言,函数可以在任何时候重新定义,因此您可以根据需要重新定义过滤器。不过,更好的解决方案可能是参数化该函数,以便它根据需要实现所需的过滤器


我需要更多的输入来提供一个足够的函数(或者甚至可能是一个足够的
grep
命令,regex可以很强大……),但是你可以想象一个函数,它可以过滤不包含前缀为
的参数的行
和所有其他的。

你的过滤器无论如何都不会工作:
grep-w PROD
与“PROD\u OPL”不匹配(因为
被认为是一个单词字符),所以
grep-v PROD\u OPL
总是不起作用(编辑:事实上,我错了,如果您得到的所有行都包含单词PROD,但不包含PROD_OPL,那么它会起作用;您不应该期望它得到的行只包含单词
PROD_something
)请参阅开始。简短回答:变量不是存储任意命令的合适位置;函数才是。您的
if
是否打算使用方括号?我在bash中从未见过
if
的paren,我的简单测试也不喜欢它们。@StephenNewell括号是无害的,但不必要。退出状态为子shell的状态只是在其中运行的管道的退出状态。@0x5453不引用
$FILTER
是错误的,但是在这里引用
$FILTER
也是错误的。(换句话说,在这里使用
FILTER
是错误的。)就其本身而言,这是正确的,但设计不好。问题是,如果
过滤器
是用户输入,您就不能真正信任内容。如果
过滤器
不是用户输入,您应该使用一个函数来代替。这可能是正确的答案,但它可能无法满足OP对
过滤器
是“动态”的需求@chepner我同意,因此有“基本示例”免责声明。在OP回答您的澄清请求之前,我会看看是否可以提供一些通用指导。
function filter() { 
    grep -w PROD | grep -v PROD_OPL
}

if (/usr/ucb/ps auxww | grep $1/$2 | filter > /dev/null)
then
  #do something
fi