2015-01-03 24 views
0

我在使用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在这个例子中的静态参数,但在真实的脚本中,参数是从HTML表单POST获得的,如果我打印,我可以看到$ fil的内容是正确的。

+0

你期望数是两个文件的总和? – SMA

+0

过滤器,我有一个有2个输入的HTML。 选择 - >所有日志 过滤器列表 - >是系统管理员可以编写 图片过滤器:http://i.imgur.com/j1WLkDu.png 所以我从“读”过滤器开关输入,但是当我想使用cat $ log $ fil时,我得到一个错误。所以我需要知道这些线需要用头部和尾部管道做一段时间才能显示过滤的信息。 – Guille

+0

您正在使用'cat ... | grep'反模式。只需要'grep'文件,不要'cat'到'grep'。另外,你应该在这里使用引号('“”')。所以试试'\'“$ string”\''。这几乎肯定是解决您的问题的错误方法,但您提供的信息太少,无法提供更好的方法。 –

回答

2

首先,请允许我说,这听起来像一个非常糟糕的主意:

[…在实际的脚本,参数是从HTML表单POST获得,[…]

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

其次,|里面的变量不被视为特殊。这不是特定于反引号。参数扩展(例如,用| grep LSmonitor代替$fil)在之后发生该命令被解析并且大部分被处理。对参数扩展的结果(包括“分词”)做了一些后处​​理,这就是为什么$fil等于三个参数'|' grep LSmonitor而不是单个参数'| grep LSmonitor'),但没有像描述的那么戏剧化。因此,举例来说,这样的:

pipe='|' 
echo $pipe cat 

打印此:

| cat 

由于您的使用情况是如此可怕,我是半个诱惑,解释如何做你想—我认为你会更好而不是这样做—但由于堆栈溢出答案旨在为更多的人使用,而不仅仅是原始的海报,下面是一个如何做到这一点的例子。我鼓励OP不要继续阅读。


fil='| grep LSmonitor' 
log=/var/log/sys.log 

string="cat $log $fil | wc -l" 
lines="$(eval "$string")" 
echo "$lines" 
3

在这种情况下,因为你正在构建一个管道为一个字符串,你将需要:

eval "$string" 

不要这样做!!!! - 有人可以很容易地进入过滤器

; rm -rf * 

然后你被洗净。

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

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

更糟的是'; rm -rf/*',特别是提升特权。 – neverendingqs

-2

尝试使用eval(从https://stackoverflow.com/a/11531431/2687324拍摄)。

它看起来像它的解释|作为一个字符串,而不是管,所以当它到达-l,它把它当作如果你想传递给-l代替catwc

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

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

+2

对于“这首先是一个非常糟糕的主意并且不这样做?解释会有帮助。 (我同意你不应该这样做)。 – neverendingqs