Long maintenance jobs do not always need a clock time; sometimes they just need a quieter system. The batch command in Linux queues shell commands for atd and starts them when the system load average drops below the daemon’s configured threshold.
The name also causes confusion with Windows batch files. Linux does not need .bat files for this workflow; write a shell command or shell script, then submit it to batch through standard input. From there, atq, at -c, and atrm let you inspect and cancel queued work before it runs.
Understand the batch Command in Linux
batch belongs to the same tool family as at. The at command runs a job at a chosen time, while batch runs a one-time job when the load average permits it. The queued job runs through /bin/sh, not necessarily your interactive shell, so Bash-specific syntax belongs inside a script with a Bash shebang or inside an explicit Bash command.
batch Command Quick Reference
| Task | Command Pattern | What It Does |
|---|---|---|
| Check availability | command -v batch | Prints the path when the command is installed. |
| Queue one command or script | printf '%s\n' "$HOME/scripts/job.sh" | batch | Submits one command line to run when load permits. |
| Queue a job file | batch < "$HOME/scripts/job.batch" | Reads multiple commands from a file. |
| List queued jobs | atq | Shows pending at and batch jobs. |
| Inspect a queued job | at -c 12 | Prints the stored shell script for job 12. |
| Cancel a queued job | atrm 12 | Removes job 12 before it starts. |
batch Jobs Are Not Windows Batch Files
A Linux batch job is a queued shell command. A Windows .bat file is a script for cmd.exe, and Linux shells do not treat the .bat extension as special. If you searched for a Linux batch file, the usual Linux equivalent is a shell script submitted to batch:
mkdir -p "$HOME/scripts"
cat > "$HOME/scripts/report-job.sh" <<'EOF'
#!/usr/bin/env bash
date
uptime
df -h "$HOME"
EOF
chmod +x "$HOME/scripts/report-job.sh"
printf '%s\n' "$HOME/scripts/report-job.sh" | batch
If you truly need to run a Windows .bat script, use a Windows-compatible environment such as Wine or a Windows VM. The Linux batch command schedules shell work; it does not translate Windows command syntax.
How batch Uses System Load
Do not assume one default load threshold across every distribution. Debian and Ubuntu builds document 1.5, while Arch documents 0.8; either way, atd owns the value and administrators can start the daemon with -l to change it. Check man atd on the target system before relying on a specific number.
Do not treat
batchas a precise off-peak scheduler. It is useful when timing is flexible and system load matters more than a clock time.
Install the batch Command
Most distributions provide batch, at, atq, and atrm from a package named at. Check for the command before installing anything:
command -v batch
A working installation prints a path similar to this:
/usr/bin/batch
If no path appears, install the at package for your distribution.
Install batch on Debian, Ubuntu, or Linux Mint
sudo apt install at
On Ubuntu, at is packaged in Universe. If APT cannot locate the package, enable the component first; the Ubuntu Universe and Multiverse repository guide shows the component check.
Install batch on Fedora
sudo dnf install at
Install batch on RHEL, CentOS Stream, Rocky Linux, or AlmaLinux
sudo dnf install at
Install batch on Arch Linux
sudo pacman -S at
Install batch on openSUSE Tumbleweed
sudo zypper install at
Official openSUSE package listings separate Tumbleweed and Leap availability. Check the package listing first on Leap systems instead of assuming the same repository coverage.
Install batch on Void Linux
sudo xbps-install at
On systemd-based distributions, enable and start the atd service after installation:
sudo systemctl enable --now atd
Verify that the daemon is active:
systemctl is-active atd
active
On non-systemd distributions, start the packaged atd service with that distribution’s service manager. For runit systems, confirm the installed service directory name before linking it under /var/service/.
Practical batch Command Examples
Queue a Single Command with batch
Use printf to submit one command line. This pattern avoids shell-specific echo behavior and keeps the queued command visible:
printf '%s\n' 'uptime > "$HOME/batch-uptime.txt"' | batch
A successful submission prints a warning about /bin/sh, then a job number and queued time:
warning: commands will be executed using /bin/sh job 6 at Sat May 9 11:10:00 2026
The warning is normal. It means the stored job runs under /bin/sh, so keep commands POSIX-compatible or call a script that starts with the shell you need.
Queue a Shell Script with batch
A shell script is easier to maintain than a long one-line job. This example creates a simple backup script that archives a documents directory into $HOME/backups:
mkdir -p "$HOME/scripts" "$HOME/backups"
cat > "$HOME/scripts/backup-documents.sh" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
source_name="Documents"
source_dir="$HOME/$source_name"
backup_dir="$HOME/backups"
if [ ! -d "$source_dir" ]; then
printf '%s\n' "Source directory not found: $source_dir" >&2
exit 1
fi
tar -czf "$backup_dir/documents-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$HOME" "$source_name"
EOF
chmod +x "$HOME/scripts/backup-documents.sh"
The script uses tar -czf with -C "$HOME" so the archive stores the Documents directory name instead of an absolute home path. The date value keeps each archive name unique, and the early directory check prevents a silent backup of the wrong path. The mkdir command examples cover nested directory creation, the chmod command guide explains the executable bit, and the guide to opening .gz and .tgz files in Linux covers how to inspect or extract the archive later.
Submit the script to batch:
printf '%s\n' "$HOME/scripts/backup-documents.sh" | batch
List pending jobs with atq before the daemon starts them:
atq
Relevant output includes the job number, queued time, queue letter, and user:
6 Sat May 9 11:10:00 2026 b user
The b queue identifies a batch job. Regular at jobs usually use the a queue unless another queue is selected.
Queue Multiple Commands from a Job File
For multi-step maintenance work, put the commands in a job file and redirect that file into batch. The commands run in order, but a failed command does not stop later commands unless your script or job file handles errors.
mkdir -p "$HOME/scripts" "$HOME/reports"
cat > "$HOME/scripts/health-report.batch" <<'EOF'
{
date
uptime
df -h "$HOME"
free -h
} > "$HOME/reports/health-report.txt"
EOF
batch < "$HOME/scripts/health-report.batch"
Use a real shell script instead when the workflow needs strict error handling, functions, traps, or Bash-only features. A job file is best for a short sequence of ordinary shell commands.
Inspect a Queued batch Job
Before a queued job starts, inspect the stored script with at -c and the job number from atq:
at -c 6
The full output includes environment variables captured at submission time. The useful lines are usually near the end:
#!/bin/sh
# atrun uid=1000 gid=1000
# mail user 0
cd /home/user || {
echo 'Execution directory inaccessible' >&2
exit 1
}
/home/user/scripts/backup-documents.sh
This check is especially useful when a job was submitted from a different directory or when a script depends on environment variables.
Cancel a Pending batch Job
Use atrm with the job number while the job is still queued:
atrm 6
atrm prints nothing when it removes a pending job. If the job no longer exists, the error looks like this:
Cannot find jobid 6
Run atq again to confirm the job disappeared from the queue.
Capture batch Job Output in a Log File
By default, output from at and batch jobs is mailed to the submitting user when a local mail transport is configured. On many desktops and minimal servers, local mail is not set up, so redirect output inside the queued command:
mkdir -p "$HOME/logs"
printf '%s\n' '"$HOME/scripts/backup-documents.sh" > "$HOME/logs/backup-documents.log" 2>&1' | batch
After the job runs, inspect the log with tail. The tail command examples explain follow mode and line-count options for longer logs.
tail "$HOME/logs/backup-documents.log"
Advanced batch Command Notes
Use at -b for at-Compatible batch Submission
The at man page documents at -b as an alias for batch. On Debian and Ubuntu’s at implementation, the standalone batch command accepts no options:
batch -q c
batch accepts no parameters
If you need an at option such as -M to suppress mail, put the option before -b:
at -M -b < "$HOME/scripts/health-report.batch"
To read a file through at instead of shell input redirection, keep -f before -b as well:
at -f "$HOME/scripts/health-report.batch" -b
Keep
at -bfor batch-style submission only. Do not append a time specification after-b; useatwithout-bwhen the job must run at a specific time.
Use Background Processes When You Need Immediate Parallel Work
batch is not a substitute for background execution in the current shell. If you need to start a command immediately and wait for it later, use shell job control or the Bash wait builtin. The bash wait command guide covers that parallel-script pattern.
Compare batch, at, and cron
Choose the scheduler based on what should trigger the job: system load, a specific time, or a recurring calendar rule.
| Tool | Trigger | Repeats Automatically | Best Fit |
|---|---|---|---|
| batch | Load average falls below the atd threshold | No | Flexible, resource-heavy work such as compression, reports, or imports |
| at | A specific time expression such as now + 2 hours | No | One-time jobs that must start at a chosen time |
| cron | A recurring schedule such as hourly, daily, or weekly | Yes | Repeated maintenance where timing matters more than current load |
Use batch when a job can wait for lower load. Use at when the start time matters. Use cron when the same command should run repeatedly.
Troubleshoot Common batch Command Errors
batch Command Not Found
If the shell cannot find batch, the at package is missing or the command is not in PATH.
batch: command not found
Install the at package for your distribution, then confirm the binary path:
command -v batch
/usr/bin/batch
batch Jobs Never Leave the Queue
If jobs remain queued for a long time, the system load may be above the atd threshold.
uptime
Relevant output includes the one-minute, five-minute, and fifteen-minute load averages:
11:30:00 up 10 days, 5:42, 2 users, load average: 2.15, 1.98, 1.87
If the one-minute value stays above the configured threshold, batch waits. Check man atd or the daemon startup options when you need the exact threshold for that system. For a job that must start at a specific time, resubmit it with at instead of batch.
atd Is Not Running
If batch cannot signal the daemon, job submission can show this error:
Can't open /run/atd.pid to signal atd. No atd running?
On a systemd distribution, start the daemon and check its active state:
sudo systemctl enable --now atd
systemctl is-active atd
active
Permission Denied When Submitting batch Jobs
Access to at and batch is controlled by /etc/at.allow and /etc/at.deny. A denied user may see an error like this:
You do not have permission to use at.
Check which access files exist:
for file in /etc/at.allow /etc/at.deny; do
[ -e "$file" ] && ls -l "$file"
done
Common Debian-family output shows /etc/at.deny only:
-rw-r----- 1 root daemon 144 Feb 4 04:39 /etc/at.deny
If /etc/at.allow exists, only users listed there may submit jobs. If it does not exist, users not listed in /etc/at.deny may submit jobs. Ask an administrator to update the appropriate file rather than editing access policy blindly.
batch Job Output Disappears
When a local mail transport is absent, command output may not reach you even though the job ran. Redirect output to a log file inside the queued command:
mkdir -p "$HOME/logs"
printf '%s\n' 'uptime > "$HOME/logs/batch-uptime.log" 2>&1' | batch
After the job runs, verify the log exists and contains output:
test -s "$HOME/logs/batch-uptime.log" && tail "$HOME/logs/batch-uptime.log"
Clean Up Example batch Files
If you only created the sample jobs for practice, remove the exact scripts, reports, and logs from the examples. Review anything under $HOME/backups before deleting it, because the archive may contain real documents. The rmdir command guide explains why the final cleanup command removes only empty directories.
rm -f "$HOME/scripts/report-job.sh" \
"$HOME/scripts/backup-documents.sh" \
"$HOME/scripts/health-report.batch" \
"$HOME/batch-uptime.txt" \
"$HOME/reports/health-report.txt" \
"$HOME/logs/backup-documents.log" \
"$HOME/logs/batch-uptime.log"
rmdir "$HOME/scripts" "$HOME/reports" "$HOME/logs" "$HOME/backups" 2>/dev/null || true
Remove the batch Command Package
Remove the at package only when no users or scripts depend on at, batch, atq, or atrm. Check the queue first:
atq
No output means there are no queued jobs for your user. Remove any pending jobs you own before uninstalling the package:
atrm 6
On Debian, Ubuntu, and Linux Mint, remove the package with APT:
sudo apt remove at
On Fedora, RHEL, CentOS Stream, Rocky Linux, or AlmaLinux, remove it with DNF:
sudo dnf remove at
On Arch Linux, use pacman:
sudo pacman -Rs at
On openSUSE Tumbleweed, use zypper:
sudo zypper remove at
On Void Linux, use xbps:
sudo xbps-remove at
Verify the batch command is gone:
command -v batch || echo "batch not found"
batch not found
Conclusion
batch gives you a load-aware queue for one-time shell work, with atq for visibility, at -c for inspection, and atrm for cleanup. Use it for flexible jobs that can wait for lower system load, and switch to at or cron when clock time or recurrence matters more.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>