反引号无法处理变量中的管道

时间:2015-01-03 17:54:29

标签: linux bash

我在使用CAT命令的bash中遇到一个脚本有问题。

这有效:

 #!/bin/bash
fil="| grep LSmonitor";
log="/var/log/sys.log ";
lines=`cat $log | grep LSmonitor | wc -l`;
echo $lines;

输出:139

这不是:

#!/bin/bash
fil="| grep LSmonitor";
log="/var/log/sys.log ";

string="cat $log $fil | wc -l";
echo $string;
`$string`;

输出:

cat /var/log/sys.log | grep LSmonitor | wc -l
cat: opcion invalida -- 'l'
Pruebe 'cat --help' para mas informacion.

$ fil是这个示例中的参数static,但在实际脚本中,参数是从html表单POST获取的,如果我打印,我可以看到$ fil的内容是正确的。

3 个答案:

答案 0 :(得分:3)

在这种情况下,由于您要将管道构建为字符串,因此您需要:

eval "$string"

不要这样做!!!! - 有人可以轻松进入过滤器

; rm -rf *

然后你就被软管了。

如果你想要一个基于正则表达式的过滤器,让用户只需输入正则表达式,然后你就可以了:

grep "$fil" "$log" | wc -l

答案 1 :(得分:2)

首先,请允许我说这听起来像个坏主意:

  

[...]在实际脚本中,参数是从html表单POST,[...]

获取的

您不应该允许shell运行POST请求的内容。这是一个巨大的攻击媒介,无论你采取什么机制来保护它,都可能没有你想象的那么有效。

其次,变量内的|不被视为特殊。这不是反对的特定内容。在解析并主要处理命令之后,参数扩展(例如,用$fil替换| grep LSmonitor)发生。对参数扩展的结果进行了一些后处​​理(包括“分词”,这就是$fil等同于三个参数'|' grep LSmonitor而不是单个参数{{}的原因。 1}}),但没有你描述的戏剧性。所以,例如,这个:

'| grep LSmonitor'

打印出来:

pipe='|'
echo $pipe cat

由于你的用例非常可怕,我很想去解释你如何做你想做的事 - 我想你会好起来而不是这样做 - 但是因为Stack Overflow的答案对于更多的人而言只是对原始海报有用,下面是一个如何做到这一点的例子。我鼓励OP不要继续阅读。


| cat

答案 2 :(得分:-2)

尝试使用eval(取自https://stackoverflow.com/a/11531431/2687324)。

看起来它将|解释为字符串,而不是管道,因此当它到达-l时,它会将其视为您尝试将-l传递给cat {1}}代替wc

其他答案概述了为什么你不应该这样做。

grep LSmonitor /var/log/syslog | wc -l会做你想要的。