我想使用watch
以下命令链的命令:
journalctl | grep 'UFW BLOCK' | grep 'DST=192.168.0.2' | awk '{printf "%-4s%-3s%-10s%-1s%+16s\n", $1, $2, $3, $7, $11, $18, $19}'
通常,当我想应用于watch
命令链时,我会将命令链括在引号之间
watch "COMMAND_1 | COMMAND_2 | ... | COMMAND_n"
但是当像上面这样的命令之一中有另一个引号时,就会出错。这个问题的解决方法是什么?
答案1
为了避免担心引号,您可以使用此处的文档:
shell_code=$(cat << 'EOF'
journalctl |
awk '
/UFW BLOCK/ && index($0, "DST=192.168.0.2 ") {
printf "%-4s%-3s%-10s%-1s%+16s\n", $1, $2, $3, $7, $11, $18, $19
}'
EOF
)
watch "$shell_code"
(或者,watch sh -c "$shell_code"
如果您的watch
实现尚未启动 shell 来解释命令行,而是运行命令本身,尽管这些watch
实现现在越来越少了)。
其他一些注意事项:
awk
可以做大部分grep
可以做的事情,所以你很少需要将它们连接在一起。.
是匹配任何单个字符的正则表达式运算符。grep 192.168.0.2
将匹配于192.168.012
.您可以使用[.]
or\.
对其进行转义,或者-F
使用 ingrep
或index()
inawk
进行子字符串搜索,而不是使用正则表达式匹配。如果您不在搜索字符串中添加额外的空格,您还会找到
DST=192.168.0.2
例如DST=192.168.0.234
。使用grep -Fw DST=192.168.0.2
将解决这两个问题。我会避免使用双引号来括起 shell 代码,因为很容易忘记转义
$
s 或`
s 并引入命令注入漏洞(变量的内容可能被解释为 shell 代码)。单引号更安全,因为可以保证其中没有特殊字符。由于这包括'
s 本身(至少在类似 Bourne 的 shell 中),这意味着您不能'
在 中包含 s'...'
,但您始终可以将它们输入为'foo'\''bar'
,它'foo'
与\'
('
用反斜杠引用)连接'bar'
。所以在这里:watch 'journalctl | awk '\'' /UFW BLOCK/ && index($0, "DST=192.168.0.2 ") { printf "%-4s%-3s%-10s%-1s%+16s\n", $1, $2, $3, $7, $11, $18, $19 }'\'
journalctl
有一个-f
/--follow
模式,新日志条目到达时会显示它们。您可能想使用它,而不是一遍又一遍地搜索完整日志。
1运行watch
的实现解释其参数与空格串联的代码,但可以直接使用/选项运行命令,从而使您可以更轻松地让其他语言解释器(如或 )解释代码。procps-ng
sh
-x
--exec
watch -x zsh -c 'zsh code'
watch -x perl -e 'perl code'
² 不过为了完整性,如果启用该选项,zsh(类似 Bourne;虽然也具有 rc 和 csh 的功能)可以'foo''bar'
在单引号字符串中包含单引号。rc
rcquotes