Unix & Linux
linux bash awk rhel cron
Updated Mon, 03 Oct 2022 16:12:48 GMT

bash + monitor disk space usage and execute script if used space reached the threshold


We want to follow the used space of /var/hadoop/hdfs partition , by way if used space is more the 50% then as results we run the script do_action.bash , finally this command should be in crontab and should be run every 1 hour

Example of the partition hdfs

df -Ph | grep 'hdfs'
/dev/sdc                     20G  1.7G   18G   9% /var/hadoop/hdfs

What we did until now is the below syntax that print "run the script do_action.bash" , in case threshold is more then 50% used ,

df -Ph | grep 'hdfs' | sed s/%//g | awk '{ if($5 > 50) print "run the scriot do_action.bash"}'

but how to add the execution of the script - do_action.bash

we try

df -Ph | grep 'hdfs' | sed s/%//g | awk '{ if($5 > 50) print "run the scriot do_action.bash"}' && bash /opt/do_action.bash

but above isnt right because script - /opt/do_action.bash runs in any case




Solution

You can run df /path/to/directory to get the df output of that directory. For example, on my system:

$ df -Ph /home/terdon
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p6  669G  186G  450G  30% /home

So you don't need to grep hdfs, you can get it directly and then simply look at the second line (NR==2 in awk) to skip the header. With that in mind, you can then set awk's exit status using exit() and use that with the regular shell && to execute your script. Something like this:

df -Ph /var/hadoop/hdfs | tr -d '%' | 
    awk 'NR==2{ exit $5>50 ? 0 : 1}' && /opt/do_action.bash

Or even shorter:

df -Ph /var/hadoop/hdfs | awk 'NR==2{exit ((0+$5) <= 50)}' && /opt/do_action.bash

&& means "only run the next command if the previous command was successful". The exit $5>50 ? 0 : 1 will set the awk command's exit code to 0 (success) if $5 is greater than 50, so the script will only run if $5>50.

Here's the first awk script written in a more verbose, but easier to understand form:

awk '{ 
        if(NR==2){ 
            if($5>50){
              exitStatus=0
            }
            else{
               exitStatus=1
            }
            exit(exitStatus)
        }
    }'




Comments (3)

  • +0 – is it possible to run additional script over pipe ? as && /opt/do_action.bash && && /opt/do_action_1.bash && && /opt/do_action_2.bash — Aug 04, 2022 at 16:13  
  • +0 – @yael yes, of course, there is no limit (there is a limit, but it's very high and is more about MAX_ARGS than the number of commands per se). You can do command1 && command2 && command3 && command4 && command5 && command6 and each will only run if the previous one was successful. — Aug 04, 2022 at 16:14  
  • +1 – To paraphrase Crocodile Dundee: That (&&) isn't pipe, THIS (|) is a pipe. — Aug 07, 2022 at 15:25