How to Use the Batch Command in Linux

The batch command schedules commands to run when system load drops below a threshold, making it ideal for resource-intensive tasks that do not require immediate execution. Unlike cron jobs that run at specific times or the at command that executes at a precise moment, batch waits for favorable system conditions before starting your tasks. This approach prevents resource contention and ensures your scheduled operations do not degrade system responsiveness.

Common use cases include running overnight backups, compressing large log archives, generating system reports, and performing maintenance tasks during periods of low activity. Because batch monitors the system load average, your tasks run when the system has spare capacity rather than competing with active users or services. As a result, batch is particularly useful on shared servers or workstations where resource availability fluctuates throughout the day.

Prerequisites

Before using the batch command, ensure the at package is installed and the atd daemon is running. On most Linux distributions, this package provides both the at and batch commands.

For Debian-based systems (Debian, Ubuntu, Linux Mint):

sudo apt install at

For Fedora:

sudo dnf install at

For RHEL, CentOS Stream, Rocky Linux, and AlmaLinux:

sudo dnf install at

For Arch Linux:

sudo pacman -S at

For openSUSE:

sudo zypper install at

For Void Linux:

sudo xbps-install at

Void Linux uses runit instead of systemd. To enable the atd service on Void Linux, run sudo ln -s /etc/sv/atd /var/service/ and then sudo sv start atd to start it.

Once installed, verify the atd service is running. For systemd-based distributions, use:

sudo systemctl status atd

Expected output shows the service is active:

● atd.service - Deferred execution scheduler
     Loaded: loaded (/lib/systemd/system/atd.service; enabled)
     Active: active (running) since Mon 2025-12-23 10:00:00 UTC
   Main PID: 1234 (atd)
      Tasks: 1 (limit: 4915)
     Memory: 512.0K
        CPU: 10ms
     CGroup: /system.slice/atd.service
             └─1234 /usr/sbin/atd -f

If the service is not running, start and enable it:

sudo systemctl enable --now atd

Understanding Batch Command Syntax

The batch command reads commands from standard input and queues them for execution when the system load average drops below a threshold. By default, this threshold is 1.5, which means batch waits until the one-minute load average falls below 1.5 before running queued jobs. On a single-core system, a load of 1.5 indicates the CPU is fully utilized with additional tasks waiting. In contrast, on multi-core systems, this threshold is more easily reached.

The load threshold of 1.5 is the default value. System administrators can change this value when starting the atd daemon using the -l option. For example, atd -l 2.0 would only run batch jobs when the load drops below 2.0.

Unlike many Linux commands, batch accepts no command-line parameters. Instead, the basic usage pattern involves piping commands or redirecting input from a file:

batch

When invoked without input redirection, batch opens an interactive prompt where you can type commands. After entering your commands, press Ctrl+D to submit the job. Alternatively, you can press Ctrl+C to cancel without submitting.

Piping Commands to Batch

The most common method for scheduling a single command is piping it through echo:

echo "/path/to/backup.sh" | batch

After submitting a job, batch confirms the job was queued:

warning: commands will be executed using /bin/sh
job 3 at Mon Dec 23 12:00:00 2025

The warning message indicates that batch uses /bin/sh to execute commands, not your current shell. This affects which shell features and environment variables are available during execution.

Scheduling from a Job File

For multiple commands or complex scripts, redirect input from a file:

batch < /path/to/jobfile.txt

The job file can contain any sequence of shell commands. Each command executes in order, and the job completes when all commands finish. However, if any command fails, subsequent commands still run unless you include explicit error handling in your script.

Viewing Queued Jobs

Use the atq command to list pending batch jobs:

atq

Example output showing two pending jobs:

3       Mon Dec 23 12:00:00 2025 b root
5       Mon Dec 23 12:05:00 2025 b root

The output columns show the job number, scheduled time, queue letter (b indicates a batch job), and the username that submitted the job. Batch jobs use the “b” queue to distinguish them from regular at jobs, which use the “a” queue.

Viewing Job Contents

Before a job executes, you can inspect its contents to verify what commands will run. Use the at -c command followed by the job number:

at -c 3

This displays the complete job script, including environment variables that will be set during execution:

#!/bin/sh
# atrun uid=1000 gid=1000
# mail user 0
umask 22
HOME=/home/user; export HOME
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
SHELL=/bin/bash; export SHELL
...
cd /home/user || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
/home/user/scripts/backup.sh

This feature helps you confirm the correct commands are queued, especially when troubleshooting jobs that do not produce expected results.

Removing Pending Jobs

To cancel a scheduled job, pass its job number to atrm:

atrm 3

This command produces no output on success. To verify the job was removed, run atq again. If you attempt to remove a job that does not exist, atrm reports an error:

Cannot find jobid 3

Practical Examples

The following examples demonstrate common batch command use cases. Each example includes the complete workflow from scheduling through verification.

Schedule a System Backup

Creating scheduled backups ensures your data is protected without requiring manual intervention. This example creates a compressed archive of a directory when system load permits.

First, create a backup script at /home/user/scripts/backup.sh:

#!/bin/bash
tar -czf /backup/documents_$(date +%Y%m%d_%H%M%S).tar.gz /home/user/documents

The -czf flags tell tar to create a gzip-compressed archive. The date command appends a timestamp to ensure each backup has a unique filename.

Make the script executable using the chmod command:

chmod +x /home/user/scripts/backup.sh

Schedule the backup to run when system load is low:

echo "/home/user/scripts/backup.sh" | batch

Verify the job is queued:

atq

Expected output:

6       Mon Dec 23 14:30:00 2025 b user

Generate a System Health Report

System administrators often generate health reports during off-peak hours. This example creates a comprehensive report including disk usage, memory status, and active processes.

Create a health check script at /home/user/scripts/system_health.sh:

#!/bin/bash
REPORT="/home/user/reports/health_$(date +%Y%m%d_%H%M%S).txt"

echo "System Health Report - $(date)" > "$REPORT"
echo "==============================" >> "$REPORT"
echo "" >> "$REPORT"

echo "DISK USAGE:" >> "$REPORT"
df -h >> "$REPORT"
echo "" >> "$REPORT"

echo "MEMORY USAGE:" >> "$REPORT"
free -h >> "$REPORT"
echo "" >> "$REPORT"

echo "LOAD AVERAGE:" >> "$REPORT"
uptime >> "$REPORT"
echo "" >> "$REPORT"

echo "TOP 10 PROCESSES BY CPU:" >> "$REPORT"
ps aux --sort=-%cpu | head -11 >> "$REPORT"

echo "Report saved to $REPORT"

Make the script executable and schedule it:

chmod +x /home/user/scripts/system_health.sh
echo "/home/user/scripts/system_health.sh" | batch

Sample Report Output

When the job completes, a sample report might look like this:

System Health Report - Mon Dec 23 15:00:00 UTC 2025
==============================

DISK USAGE:
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       100G   45G   50G  48% /
/dev/sdb1       500G  200G  275G  43% /data

MEMORY USAGE:
              total        used        free      shared  buff/cache   available
Mem:           16Gi       4.2Gi       8.1Gi       256Mi       3.7Gi        11Gi
Swap:          4.0Gi          0B       4.0Gi

LOAD AVERAGE:
 15:00:00 up 30 days,  2:15,  3 users,  load average: 0.52, 0.78, 0.91

TOP 10 PROCESSES BY CPU:
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0 169936 12288 ?        Ss   Nov23   0:15 /sbin/init
...

Schedule Multiple Commands in Sequence

For complex maintenance tasks, you can queue multiple commands that execute in sequence. This example updates package lists, performs upgrades, and cleans up unused packages.

Create a maintenance file at /home/user/scripts/maintenance.txt:

apt update
apt upgrade -y
apt autoremove -y
apt clean

Schedule the maintenance job:

sudo batch < /home/user/scripts/maintenance.txt

When scheduling commands that require root privileges, run batch with sudo. The job inherits the privileges of the user who submitted it, so commands requiring root access must be submitted by root or via sudo.

Batch vs At vs Cron: When to Use Each

Linux provides multiple scheduling mechanisms, each designed for different scenarios. Understanding when to use each tool helps you choose the right approach for your tasks. The following table summarizes the key differences:

ToolTriggerRecurrenceBest For
batchSystem load drops below 1.5One-timeBackups, log processing, batch imports
atSpecific time (e.g., 3:00 AM)One-timeMaintenance windows, time-sensitive tasks
cronRecurring scheduleRepeatingDaily backups, weekly reports, regular maintenance

Choosing the right tool: Use batch when the task is resource-intensive and timing is flexible, since it waits for favorable system conditions. Use at when the task must run at a specific time regardless of system load. Choose cron when the task needs to run repeatedly on a defined schedule. For related scheduling concepts, see our guide on the bash wait command for managing background processes in scripts.

Troubleshooting

Jobs Never Execute

If your batch jobs remain in the queue indefinitely, the system load may never drop below the threshold. To diagnose this issue, check the current load average:

uptime

Example output:

 15:30:00 up 10 days,  5:42,  2 users,  load average: 2.15, 1.98, 1.87

The three numbers represent the one-minute, five-minute, and fifteen-minute load averages. If the one-minute average consistently exceeds 1.5, batch jobs will not run. On heavily loaded servers, consider using the at command instead to schedule the task at a specific off-peak time.

atd Service Not Running

If you see the error “Can’t open /run/atd.pid to signal atd. No atd running?” the scheduling daemon is not active. Start the service:

sudo systemctl start atd

Verify it started successfully:

sudo systemctl status atd

To ensure atd starts automatically on boot:

sudo systemctl enable atd

Permission Denied Errors

If batch reports permission errors, check the /etc/at.allow and /etc/at.deny files. These files control which users can schedule at and batch jobs.

The access control logic works as follows: if /etc/at.allow exists, only users listed in that file can use batch. If /etc/at.allow does not exist, all users except those listed in /etc/at.deny can use batch. By default, most distributions ship with /etc/at.deny as an empty or near-empty file, allowing all regular users to use batch. Check your system’s configuration:

ls -la /etc/at.allow /etc/at.deny 2>/dev/null

If you need access but are denied, ask your system administrator to add your username to /etc/at.allow or remove it from /etc/at.deny.

Commands Fail Silently

By default, batch mails output to the user who submitted the job. If mail is not configured on your system, you may not see error messages. To capture output manually, redirect it within your commands:

echo "/home/user/scripts/backup.sh > /home/user/logs/backup.log 2>&1" | batch

This redirects both standard output and standard error to a log file you can review later.

Remove the at Package

If you no longer need batch scheduling functionality, you can remove the at package. First, ensure no pending jobs remain:

atq

Remove any pending jobs before uninstalling:

atrm 3 5 7

For Debian-based systems:

sudo apt remove at
sudo apt autoremove

For Fedora, RHEL, and derivatives:

sudo dnf remove at

For Arch Linux:

sudo pacman -Rs at

For openSUSE:

sudo zypper remove at

For Void Linux:

sudo xbps-remove at

Verify removal:

which batch

If removal was successful, the command returns no output. Alternatively, you can verify using command -v batch, which also returns nothing when the package is no longer installed.

Conclusion

The batch command provides efficient load-aware task scheduling for non-time-critical operations like backups, report generation, and maintenance scripts. Combined with atq for monitoring pending jobs, at -c for inspecting job contents, and atrm for cancellation, you have complete control over queued tasks. This approach ensures resource-intensive operations run only when your system has spare capacity, preventing performance degradation during peak usage periods.

Leave a Comment