我正在尝试运行这个 nagios 插件:
sudo /usr/lib64/nagios/plugins/check_generic.pl -n "slab_mem" -e "SLAB=$$(cat /proc/meminfo | egrep "Slab:" | awk '{print $$2;}'); MEMTOTAL=$$(cat /proc/meminfo | egrep "MemTotal:" | awk '{print $2;}'); awk "BEGIN {print 100*$$SLAB/$$MEMTOTAL}"" -w '>50' -c '>80' -p "slab_mem"
它显示了这个错误:
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `SLAB=76876(cat /proc/meminfo | egrep "Slab:" | awk '{print 768762;}'); MEMTOTAL=76876(cat /proc/meminfo | egrep "MemTotal:" | awk '{print ;}'); awk BEGIN 1>/var/tmp/check_generic/check_generic_stdout_77319.64001 2>/var/tmp/check_generic/check_generic_stderr_77319.23364'
slab_mem UNKNOWN - result:RC1 output: match:RC!=OK |slab_mem=;50.000000;80.000000;;
我发现转义(
可以)
使其工作,但是它不起作用,然后出现此错误:
-bash-4.1$ /usr/lib64/nagios/plugins/check_generic.pl -n "slab_mem" -e "SLAB=$$\(cat /proc/meminfo | egrep "Slab:" | awk '{print $$2;}'\); MEMTOTAL=$$\(cat /proc/meminfo | egrep "MemTotal:" | awk '{print $2;}'\); awk "BEGIN {print 100*$$SLAB/$$MEMTOTAL}"" -w '>50' -c '>80' -p "slab_mem"
sh: /proc/meminfo: Permission denied
awk: {print 749962;})
awk: ^ syntax error
sh: /proc/meminfo: Permission denied
awk: {print ;})
awk: ^ syntax error
我在尝试读取 /proc/meminfo 时发现的唯一信息是因为有些人尝试执行它(而不是用 读取cat
),但事实并非如此。
编辑:
试图逃跑$$
:
命令:
-bash-4.1$ /usr/lib64/nagios/plugins/check_generic.pl -n "slab_mem" -e "SLAB=\$\$\(cat /proc/meminfo | egrep "Slab:" | awk '(print $$2'\) MEMTOTAL=\$\$\(cat /proc/meminfo | egrep "MemTotal:" | awk '{print $2;}'\); awk "BEGIN {print 100*\$\$SLAB/\$\$MEMTOTAL}"" -w '>50' -c '>80' -p "slab_mem"
结果:
sh: /proc/meminfo: Permission denied
awk: {print ;})
awk: ^ syntax error
awk: (print 499542)
awk: ^ syntax error
awk: cmd. line:1: (print 499542)
awk: cmd. line:1: ^ unexpected newline or end of string
slab_mem UNKNOWN - result:RC1 output: match:RC!=OK [awk: cmd. line:1: BEGIN blocks must have an action part]|slab_mem=;50.000000;80.000000;;
答案1
SLAB=76876(cat /proc/meminfo | egrep "Slab:" | awk '{print 768762;}')
shell 将其解析为这些词
SLAB="76876(cat" /proc/meminfo | egrep "Slab:" | awk '{print 768762;}')
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ .......................................^
其中“(cat”字符是 SLAB 临时环境变量值的一部分。
然后,shell 尝试调用 /proc/meminfo 作为命令。
这会留下一个不成对的右括号,从而导致 awk 语法错误
SLAB=$$
我不清楚和 的用途(cat ...)
是什么。您是否尝试设置 SLAB 变量以保存连接 pid 和括号代码结果的值?
-e
我的解决方案:我将分部分构建 nagios命令:
nagios_cmd=""
for var in Slab MemTotal; do
nagios_cmd+=$(printf '%s="${$}$(awk '\''/%s:/ {print $2}'\'' /proc/meminfo)"; ' $var $var)
done
nagios_cmd+='awk -v s="$Slab" -v m="$MemTotal" '\''BEGIN {print 100*s/m}'\'
declare -p nagios_cmd
这输出
declare -- nagios_cmd="Slab=\"\${\$}\$(awk '/Slab:/ {print \$2}' /proc/meminfo)\"; MemTotal=\"\${\$}\$(awk '/MemTotal:/ {print \$2}' /proc/meminfo)\"; awk -v s=\"\$Slab\" -v m=\"\$MemTotal\" 'BEGIN {print 100*s/m}'"
这表明外壳将保护所有需要保护的角色。
然后你调用 nagios 检查如下:
/usr/lib64/nagios/plugins/check_generic.pl -n "slab_mem" -e "$nagios_cmd" -w '>50' -c '>80' -p "slab_mem"
# ..........................................................^^^^^^^^^^^^^
它可以写成单个 awk 命令而不需要临时 shell 变量:
nagios_cmd='awk -F":" -v pid="$$" '\''
$1 == "Slab" {s = pid $2}
$1 == "MemTotal" {m = pid $2}
END {print 100*s/m}
'\'' /proc/meminfo'
或者,为了帮助解决引用地狱问题,这里有一个文档:
nagios_cmd=$(cat <<'END_CMD'
awk -F":" -v pid="$$" '
$1 == "Slab" {s = pid $2}
$1 == "MemTotal" {m = pid $2}
END {print 100*s/m}
' /proc/meminfo
END_CMD
)