19

Am trying to write a one-liner that can probe the output of df -h and alert when one of the partitions is out [or almost] of space. It's the part using xargs that kicking me in the ass now...

echo 95 | xargs -n1 -I{} [ {} -ge 95 ] && echo "No Space on disk {}% full -- remove old backups please"

How can i make the second {} show "95" too?

28

That && is not part of the xargs command, it's a completely separate invocation. I think you'll want to explicitly execute a subshell:

echo 95 | xargs -n1 -I_percent -- sh -c '[ _percent -ge 95 ] && echo "No Space on disk _percent% full -- remove old backups please"'

Note also I'm using _percent instead of {} to avoid extra quoting headaches with the shell. It's not a shell variable; still just an xargs replacement string.

0
3

An alternative way, which is more readable, is to define a separate function which contains all your other commands and then call that function with xargs in a sub-shell.

Hence, for example:

myfunc(){
  [ "$1" -ge 95 ] && echo "No Space on disk $1% full -- remove old backups please"
  echo "Another command echoing $1"
}

export -f myfunc

echo 95 | xargs -n1 -I_percent -- sh -c 'myfunc "_percent"'
0

You can just use the sh option mentioned and enclose the command in single quotes as show below with an extra equivalent if version:

#Your example
echo 95 | xargs -n1 -I{} sh -c '[ {} -ge 95 ] && echo "No Space on disk {}% full -- remove old backups please"'

#if equivalent
echo 95 | xargs -n1 -I{} sh -c 'if [ {} -ge 95 ]; then echo "No Space on disk {}% full -- remove old backups please"; fi'

Using xargs with alias in -I option for better readability

echo 95 | xargs -n1 -IusedSpace sh -c 'if [ usedSpace -ge 95 ]; then echo "No Space on disk usedSpace% full -- remove old backups please"; fi'

With if and chain as many command as You wish separated by semicolon ; below example with 2 and 4 commands chained

# 2 independent commands
echo 95 | xargs -n1 -I{} sh -c 'if [ {} -ge 95 ]; then echo "No Space on disk {}% full -- remove old backups please"; echo "Value processed {}"; fi'
# 4 independent commands
echo 95 | xargs -n1 -I{} sh -c 'if [ {} -ge 95 ]; then echo "No Space on disk {}% full -- remove old backups please"; echo "Space left on disk $( expr 100 - {})%"; echo "Space used {}%"; echo "Value processed {}"; fi'

I added the else case in your example, It prints the left disk space

#If with else block
echo 80 | xargs -n1 -I{} sh -c 'if [ {} -ge 95 ]; then echo "No Space on disk {}% full -- remove old backups please"; else echo "Space left on disk $( expr 100 - {})%"; fi'

#Equivalent
echo 80 | xargs -n1 -I{} sh -c '[ {} -ge 95 ] && echo "No Space on disk {}% full -- remove old backups please"; [ {} -ge 95 ] || echo "Space left on disk $( expr 100 - {})%"'

Another modification could be isolate the 95 percent of limit usage in a variable as show below:

echo 96 | xargs -n1 -IusedSpace sh -c 'usageLimit=95; if [ usedSpace -ge ${usageLimit} ]; then echo "No Space on disk usedSpace% full -- remove old backups please"; else echo "Space left on disk $( expr 100 - usedSpace)%"; fi'

Happy scripting!!! @enrique

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.