-1

Task: Scan viruses with clamav and report if infected files exists

one line script

clamscan -ir --exclude=/proc --exclude=/sys --exclude=/dev / | grep "Infected files: [1-9].*" -z | mutt -s 'Viruses detected' -- email1@domain.com email2@domain.com email3@domain.com

Problem: Email message is sent if command "clamscan ...| grep" returned empty output (Viruses not founded, Infected files: 0)

Sub-task: Write bash script without use temporary files. Use only redirect output functions and check if output is empty then "Mutt" no to be executed

  • Can you write a small shell script to read stdin in a variable (say `$input`) and use this variable against `-z "$input"` check? – Prasanna Nov 29 '15 at 13:31

1 Answers1

2

You can't make it a one-liner without cheating.

The straightforward solution is to capture the output and use it if there was a match:

if output=$(clam etc | grep etc); then
    mutt etc <<<"$output"
fi

The cheat is to hide this functionality somehow:

mongrel () {  # aka "mutt maybe"
    input=$(cat -)
    case $input in '') return 1;; esac
    mutt "$@" <<<"$input"
}
clam etc | grep etc | mongrel etc

If there is a lot of output, I would perhaps actually prefer a temporary file over keeping the results in memory; but if this is your assignment, I won't go there.

Incidentally, the trailing wildcard in your grep regex isn't contributing any value -- unless it somehow helps your understanding (which I think it doesn't; more like it adds confusion) I would leave it out.

Only emailing the summary of the results is of dubious value -- to my mind, it would be better to send the entire report when there is an infection.

output=$(clamscan -ir --exclude=/proc --exclude=/sys --exclude=/dev /)
case $output in *"Infected files: [1-9]"*)
   mutt -s 'Viruses detected' -- email1@domain.com email2@domain.com email3@domain.com <<<"$output" ;;
esac
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thanks. Works perfectly. In one line (for simple add to cron task): if output=$(clamscan -ir --exclude=/proc --exclude=/sys --exclude=/dev / | grep "Infected files: [1-9].*" -z); then mutt -s 'Viruses detected on stkmos' -- mail@domain.com mail2@domain.com <<<"$output"; fi – Alexander Demidov Dec 03 '15 at 16:49