我在使用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的内容是正确的。
答案 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
会做你想要的。