繁体   English   中英

如何在 bash 脚本中使用 arguments 执行“runuser”命令?

[英]How do I execute a "runuser" command, with arguments, in a bash script?

我有一个利基要求,即在另一个实用程序的包装脚本中运行存储在另一个配置文件中的命令。 我的包装脚本(如下)适用于该配置文件中不使用“runuser”且还包含 arguments 的每个命令。如果命令使用 runuser 而我的“-c”命令包含 arguments,则脚本失败。

包装器脚本

#!/bin/bash
nagios_cmd=$(grep $1 /etc/nagios/nrpe.cfg | awk -F "=" {'print $2'})
exec=$($nagios_cmd)
if [ $? -eq 0 ]
then
  #exitok
  echo $exec
  exit 0
else
  #exitcritical
  echo $exec
  exit 1001
fi

配置文件

command[check_crsdb_state]=sudo /usr/lib64/nagios/plugins/check_crsdb_state
command[check_crsasm_state]=sudo /usr/lib64/nagios/plugins/check_crsasm_state
command[check_ora1_tablespace_apex]=sudo /usr/sbin/runuser -l oracle -c '/check_oracle_tablespace APEX 32000'
command[check_ora1_tablespace_lob1]=sudo /usr/sbin/runuser -l oracle -c '/check_oracle_tablespace LOB1 32000'

脚本运行成功

[root@quo-mai-ora1 /]# ./rmmwrapper.sh check_crsasm_state
OK - All nodes report 'Started,STABLE'
[root@quo-mai-ora1 /]#

脚本运行失败

[root@quo-mai-ora1 /]# ./rmmwrapper.sh check_ora1_tablespace_apex
APEX: -c: line 0: unexpected EOF while looking for matching `''
APEX: -c: line 1: syntax error: unexpected end of file
[root@quo-mai-ora1 /]#

脚本运行失败(使用 bash -x)

[root@quo-mai-ora1 /]# bash -x ./rmmwrapper.sh check_ora1_tablespace_apex
++ grep check_ora1_tablespace_apex /etc/nagios/nrpe.cfg
++ awk -F = '{print $2}'
+ nagios_cmd='sudo /usr/sbin/runuser -l oracle -c '\''/check_oracle_tablespace APEX 32000'\'''
++ sudo /usr/sbin/runuser -l oracle -c ''\''/check_oracle_tablespace' APEX '32000'\'''
APEX: -c: line 0: unexpected EOF while looking for matching `''
APEX: -c: line 1: syntax error: unexpected end of file
+ exec=
+ '[' 1 -eq 0 ']'
+ echo
+ exit 1001
[root@quo-mai-ora1 /]#

问题

您可以在 bash -x output 中看到,出于某种原因,当 $nagios_cmd 被执行时,它在空格之前放置单引号分隔提供给结果脚本 (/check_oracle_tablespace) 的多个参数。 我尝试了不同的执行 $nagios_cmd 的方法(使用反引号等。我尝试了 escaping 空格字符,方法是将配置文件修改为如下所示:

command[check_ora1_tablespace_apex]=sudo /usr/sbin/runuser -l oracle -c '/check_oracle_tablespace\ APEX\ 32000'

我还尝试在 runuser 上的 -c 之后用双引号而不是单引号封装命令,或者根本不使用引号。

我显然遗漏了 bash 的一些根本错误。如何让脚本只执行 $nagios_cmd 的纯文本内容?

这看起来像是eval实际上是正确答案的罕见情况之一。 尝试这个:

exec=$(eval "$nagios_cmd")

解释:bash 直到解析命令过程的相当晚才扩展变量,因此变量中的字符串不会像它实际上是命令的一部分那样被解析。 在这种情况下,问题是它在引号和转义符被解析后被扩展,所以多词命令周围的单引号来不及达到预期效果。 请参阅BashFAQ #50:“我试图将命令放入变量中,但复杂的情况总是失败!”

eval所做的基本上是从头开始重新运行整个命令解析过程。 因此,该变量会扩展为您要运行的命令(包括引号等),并且会像正常情况一样对其进行解析。

请注意,我确实在变量周围加上了双引号; go 通过对未引用的变量引用完成的部分解析过程,然后通过完整的解析过程。 这种一次半的解析过程可能会产生罕见但非常奇怪的效果,因此最好避免。

另外: eval的坏名声是当之无愧的(我用“massive bug ma.net”这个词来形容它)。 这是因为它从根本上来说是将数据(例如变量的内容)视为可执行代码,因此您很容易发现您正在做一些事情,例如将文件名的一部分作为命令执行。 但在这种情况下,您的数据应该一个命令,并且(希望)相信不会包含恶意、无效等内容。 在这种情况下,您希望数据被视为可执行代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM