Score:0

Error near unexpected token `(' but then permission denied

in flag

I am trying to run this nagios plugin:

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"

It shows this error:

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;;

I found that escaping ( and ) could make it work, but it doesnt, then it gives this error:

-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

The only information I found while trying to read /proc/meminfo is because some people tried to execute it (instead of reading with cat) but this is not the case.

EDIT: Trying to escape $$: Command:

-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"

Result:

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;;
Bodo avatar
pt flag
Assuming you want to pass a literal `$` to some other shell and want to prevent the expansion of by the local shell, you need `\$` instead of `$$`. `$$` is the PID of the current script. See https://unix.stackexchange.com/q/291570/330217
cn flag
`SLAB=76876(cat /proc/meminfo | ...` -- I'm not sure what you're trying to do there. Can you explain this particular snippet? I have a guess, but I'd like you to explain before I answer.
pLumo avatar
in flag
I guess it should be `SLAB=76876$(cat ...)`. You're missing a `$`.
aldegalan avatar
in flag
@Bodo But \$ does not work with the Nagios remote agent... it must be $$
Bodo avatar
pt flag
@aldegalan Then you might need `\$\$`.
aldegalan avatar
in flag
@Bodo ok, but still getting permission denied awk: `{print 499542;}) awk: ^ syntax error sh: /proc/meminfo: Permission denied awk: {print ;}) awk: ^ syntax error`
Bodo avatar
pt flag
@aldegalan As you can see in `{print 499542;})` you have the same quoting problem in the AWK command. In `$$2`, `$$` is replaced with the script's PID by the local shell followed by a literal `2`. (I don't know nagios or the check_generic plugin, so I don't know if this needs additional quoting or duplication of `$` characters.) The `Permission denied` error might be a result of other ways of wrong quoting. Please [edit] your question and add all modified versions of your script/command with the resulting error messages. Use copy&paste instead of retyping to avoid introducing unrelated errors.
aldegalan avatar
in flag
@Bodo Done, I edited my question
Bodo avatar
pt flag
@aldegalan There seems to be an issue with the quotes. If I understand correct, you try to use double quotes inside double quotes. Can you add links to some documentation that explains the arguments to `-e` and the necessary quoting? I did not find any working links for the `check_generic` plugin. Can you explain what the command list `SLAB=...` including all `awk` commands is supposed to do? Or where does this command list come from? Please [edit] your question to provide this information.
Bodo avatar
pt flag
It would help to show the command list as you would run it directly in a shell without using nagios and some example input (= output of `cat /proc/meminfo`) and corresponding output. Do I understand correct that you want to extract two numbers from `/proc/meminfo` and to calculate Slab/MemTotal in %? This could be implemented with a single `awk` command. The information about what you want to achieve would belong into the question. (Your question seem to be about shell programming and not specifically related to Ubuntu, so it might better fit on stackoverflow.com.)
Score:0
cn flag
SLAB=76876(cat /proc/meminfo | egrep "Slab:" | awk '{print 768762;}')

the shell parses that into these words

SLAB="76876(cat" /proc/meminfo | egrep "Slab:" | awk '{print 768762;}')
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ .......................................^

Where the "(cat" characters are part of the value for the SLAB temporary environment variable.

Then, the shell is attempting to call /proc/meminfo as a command.

That leaves an unpaired closing parenthesis causing the awk syntax error


I'm unclear what the purpose of SLAB=$$ and the (cat ...) is. Are you trying to set the SLAB variable to hold a value that concatenates the pid and the result of parenthesized code?


My solution: I'd build the nagios -e command in pieces:

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

This outputs

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}'"

which shows you the shell will protect all the chacters that need protecting.

Then you invoke the nagios check like:

/usr/lib64/nagios/plugins/check_generic.pl -n "slab_mem" -e "$nagios_cmd" -w '>50' -c '>80' -p "slab_mem"
# ..........................................................^^^^^^^^^^^^^

That can be written as a single awk command without needing the temporary shell variables:

nagios_cmd='awk -F":" -v pid="$$" '\''
    $1 == "Slab" {s = pid $2}
    $1 == "MemTotal" {m = pid $2}
    END {print 100*s/m}
'\'' /proc/meminfo'

Or, to help with the quoting hell, a here-document:

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
)
aldegalan avatar
in flag
So how could I resolve it? And yes, I am trying to cocnatenate the pid and the result
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.