When integrating antivirus scanning into a Linux application or upload pipeline, clamdscan is usually a much better choice than clamscan.
While clamscan starts a full standalone scan process and loads virus signatures every time, clamdscan talks to the long-running clamd daemon. This makes scans significantly faster and more suitable for production environments.
One particularly useful option is --fdpass.
What does --fdpass do?
Normally, clamd runs under its own user account, such as clamav. This can create permission issues when scanning files owned by another user or temporary upload files.
The --fdpass option solves this by passing the already opened file descriptor to the daemon instead of letting the daemon reopen the file itself.
This is especially useful for:
- Upload processing
- Temporary files
- Restricted file permissions
- CI/CD pipelines
- Web applications
Installing ClamAV
On Debian or Ubuntu systems:
sudo apt update
sudo apt install clamav clamav-daemon
Update the virus definitions:
sudo freshclam
Enabling clamd on startup
To ensure the daemon automatically starts after a reboot:
sudo systemctl enable clamav-daemon
sudo systemctl start clamav-daemon
Verify the service is running:
sudo systemctl status clamav-daemon
On some distributions, the service may be named clamd instead.
Verifying the socket configuration
clamdscan communicates with the daemon through a Unix socket.
Check the configured socket path:
grep LocalSocket /etc/clamav/clamd.conf
Typical values are:
LocalSocket /run/clamav/clamd.ctl
or:
LocalSocket /var/run/clamav/clamd.ctl
You can also locate the socket manually:
sudo find /run /var/run -name "*.ctl"
Scanning a file
To scan a file quietly:
clamdscan --fdpass --quiet myfile.zip
If the file is clean, the command exits with status code 0.
If malware is detected, the exit code becomes 1.
Example in a shell script:
if clamdscan --fdpass --quiet upload.pdf; then
echo "File is clean"
else
echo "Virus detected"
fi
Why use clamdscan instead of clamscan?
clamdscan has several advantages:
- Much faster scanning
- Lower memory usage
- Better suited for concurrent workloads
- No repeated signature loading
- Ideal for web servers and APIs
For applications handling many uploads or background jobs, using clamdscan --fdpass is generally the recommended setup.
Common error
If you encounter:
ERROR: Could not connect to clamd on LocalSocket
the daemon is usually not running.
Start it manually:
sudo systemctl start clamav-daemon
Then retry the scan command.
Understanding exit codes
When integrating clamdscan into an application or upload pipeline, it is important to distinguish between an actual virus detection and a technical failure.
Fortunately, clamdscan provides clear exit codes for this.
| Exit code | Meaning |
|---|---|
0 |
No virus found |
1 |
Virus found |
2 |
Scanner error or operational failure |
This means you should avoid parsing stdout or stderr to determine the scan result. Instead, rely on the process exit code directly.
Example:
clamdscan --fdpass --quiet upload.pdf
result=$?
case $result in
0)
echo "File is clean"
;;
1)
echo "Virus detected"
;;
2)
echo "Scan failed"
;;
esac
This distinction is especially important in automated systems:
-
Exit code
1means the scanner worked correctly and detected malware -
Exit code
2means something operational failed, such as:clamdnot running- socket connection failures
- permission issues
- corrupted scanner configuration
In production systems, a virus detection is usually a business-level validation failure, while exit code 2 should typically trigger retries, logging, monitoring, or alerts.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.