I'm running filesystem usage command to detect /var filesystem usage beyond 80% from one host to multiple remote hosts.

My command runs fine (df -h /var | awk '$1 > 80'), but with ssh it gives me syntax errors.

for i in `cat /etc/gridhosts`; do ssh -n -o BatchMode=yes ${i} "df -h /var | awk '$4 > 80'" ; done
awk:  > 80
awk:  ^ syntax error
awk:  > 80
awk:  ^ syntax error
awk:  > 80
  • 5
    $4 is being passed to ssh inside double quotes with an unescaped dollar sign. Is that intentional? – guest Mar 22 '20 at 12:12
  • @guest $4 gets the 4th field value of df command output – Mohammed Mar 22 '20 at 17:23
  • $4 does NOT get the 4th field. In the top level script, the whole command starting with df is in double quotes. Inside double quotes, the single quotes around the awk program are just characters -- they are not syntactic single quotes, they do not wrap the awk script. The $4 is exposed and substituted at the client shell, and it gets replaced by nothing before the ssh is even called. The awk program is thus merely ' > 80' and it fails. That is as shown exactly and correctly in the syntax error. – Paul_Pedant Mar 22 '20 at 19:36
  • Thanks @Paul_Pedant, I removed double quotes and it worked. – Mohammed Mar 22 '20 at 22:58

The issue is that $4 in the awk program is part of a double quoted string. Since it is in double quotes, the (local) shell will expand it before calling ssh.

In the shell, $4 is the 4th positional parameter, which most likely is empty. The means that the $4 in the awk code will be replaced by an empty string, producing an invalid awk program.

In this case, there is no need to run the awk command on the remote host. Instead, just do

while IFS= read -r remote; do
    ssh -n -o BatchMode=yes "$remote" 'df /var' | awk 'FNR == 2 && $5 > 80'
done </etc/gridhosts

Note that I've changed the awk code to look at $5 on line 2 rather than at $4 on every line, as this is where the the percentage is usually located. Also, I've removed the -h option for df as it's not needed, and I've made the loop read the input file line by line rather than expanding the full contents of the file in a for loop header (which is inelegant, and could, in the general case, eat a lot of memory unnecessarily).

You may also be interested in evaluating Ansible or similar software, as this would make doing cluster-wide operations much easier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.