xargs : using same argument in multiple commands

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?

Asked By: JWL

||

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

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

Note also that 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.

Answered By: ckhan

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"'
Answered By: shivams

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

Answered By: Enrique Palacio
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.