atq 命令(at queue)用于显示当前系统中所有待执行的 at 任务队列。它是 at 命令包的组成部分,功能与 at -l 命令完全相同。atq 提供了任务的编号、执行时间、队列和用户信息。
atq 命令随 at 软件包一起安装。在大多数 Linux 发行版中,at 命令需要单独安装:
sudo apt-get install at
sudo yum install at
# CentOS 8+使用dnf
sudo dnf install at
sudo dnf install at
sudo pacman -S at
# 启动atd服务
sudo systemctl start atd
# 设置开机自启
sudo systemctl enable atd
# 检查服务状态
sudo systemctl status atd
which atq
atq [选项] [队列]
| 选项 | 说明 |
|---|---|
-q 队列 |
仅显示指定队列的任务 |
-v 或 --version |
显示版本信息 |
-h 或 --help |
显示帮助信息 |
-V |
显示版本信息 |
$ atq
8 2024-12-25 14:30 a username
9 2024-12-31 23:59 b username
10 2025-01-01 00:00 c username
11 2025-01-15 09:00 = username
| 字段 | 说明 | 示例 |
|---|---|---|
| 任务编号 | 任务的唯一标识符,用于管理任务 | 8, 9, 10 |
| 执行时间 | 任务计划执行的日期和时间 | 2024-12-25 14:30 |
| 队列 | 任务所属的队列标识符 | a, b, = |
| 用户名 | 创建任务的用户 | username |
| 队列 | 说明 | 特点 |
|---|---|---|
a |
默认队列 | 普通优先级任务 |
b |
批处理队列 | 系统负载低时运行 |
c |
队列c | 自定义用途 |
d-z |
队列d到z | 自定义用途 |
A-Z |
队列A到Z | 大写字母队列 |
= |
运行中的任务 | 当前正在执行的任务 |
# 查看所有用户的at任务
atq
# 查看所有任务(与atq相同)
at -l
# 显示详细信息(有些版本支持)
atq -v
# 查看默认队列a的任务
atq -q a
# 查看批处理队列b的任务
atq -q b
# 查看队列c的任务
atq -q c
# 查看大写字母队列A的任务
atq -q A
# 普通用户只能查看自己的任务
atq
# root用户可以查看所有用户的任务
sudo atq
# 查看特定用户的任务(需要root权限)
sudo atq | grep username
# 按时间排序查看(结合sort)
atq | sort -k2
# 查看今天要执行的任务
TODAY=$(date +"%Y-%m-%d")
atq | grep "$TODAY"
# 查看未来24小时内的任务
atq | while read job; do
job_time=$(echo "$job" | awk '{print $2" "$3}')
job_timestamp=$(date -d "$job_time" +%s)
now_timestamp=$(date +%s)
if [ $((job_timestamp - now_timestamp)) -le 86400 ]; then
echo "$job"
fi
done
# 查看当前正在执行的任务(队列为=)
atq | grep " = "
# 结合at -c查看任务内容
atq | grep " = " | awk '{print $1}' | while read job_id; do
echo "任务 $job_id 正在运行:"
at -c "$job_id" | head -5
done
#!/bin/bash
# 批量查看所有任务的详细信息
echo "=== at任务详情报告 ==="
echo "生成时间: $(date)"
echo ""
atq | while read line; do
job_id=$(echo "$line" | awk '{print $1}')
echo "任务ID: $job_id"
echo " 基本信息: $line"
echo " 命令摘要:"
at -c "$job_id" | grep -E "^[^#]" | head -3
echo ""
done
#!/bin/bash
# 统计at任务信息
TOTAL_JOBS=$(atq | wc -l)
USER_JOBS=$(atq | grep -c "$USER")
RUNNING_JOBS=$(atq | grep -c " = ")
echo "at任务统计报告"
echo "================="
echo "总任务数: $TOTAL_JOBS"
echo "当前用户任务数: $USER_JOBS"
echo "正在运行的任务数: $RUNNING_JOBS"
echo ""
echo "按队列统计:"
atq | awk '{print $4}' | sort | uniq -c | sort -rn
# 将任务列表导出到文件
atq > /tmp/at_tasks_$(date +%Y%m%d).txt
# 导出为CSV格式
atq | awk 'BEGIN {print "任务ID,执行时间,队列,用户名"} {print $1","$2" "$3","$4","$5}' > /tmp/at_tasks.csv
# 导出为JSON格式
atq | awk 'BEGIN {print "["}
{if (NR>1) printf ",\n"; printf " {\"id\":\"%s\",\"time\":\"%s %s\",\"queue\":\"%s\",\"user\":\"%s\"}", $1, $2, $3, $4, $5}
END {print "\n]"}'> /tmp/at_tasks.json
atq 命令与 at 命令密切相关,两者都属于 at 软件包:
# 以下三个命令功能完全相同
atq
at -l
at --list
| 命令 | 功能 | 与atq的关系 |
|---|---|---|
at |
创建定时任务 | 创建的任务可用atq查看 |
atq |
查看任务队列 | 核心查看命令 |
atrm |
删除任务 | 使用atq看到的任务编号可用于atrm |
batch |
创建批处理任务 | 创建的任务在atq中显示为队列b |
at -c |
查看任务内容 | 需要atq提供的任务编号 |
# 1. 创建at任务
echo "echo 'Hello World'" | at now + 1 minute
# 2. 查看任务队列
atq
# 输出: 15 2024-01-01 10:05 a username
# 3. 查看任务内容
at -c 15 | tail -20
# 4. 等待任务执行...
# 5. 如果需要,删除任务
atrm 15
# 或者
at -d 15
#!/bin/bash
# 监控at任务,超过阈值时发送告警
MAX_JOBS=20
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/at_monitor.log"
# 获取任务数量
JOB_COUNT=$(atq | wc -l)
# 记录日志
echo "$(date): 当前at任务数: $JOB_COUNT" >> "$LOG_FILE"
# 检查是否超过阈值
if [ "$JOB_COUNT" -gt "$MAX_JOBS" ]; then
echo "警告: at任务数超过阈值 ($JOB_COUNT/$MAX_JOBS)" | \
mail -s "At任务过多告警" "$ALERT_EMAIL"
# 生成详细报告
echo "详细任务列表:" >> /tmp/at_alert.txt
atq >> /tmp/at_alert.txt
echo "" >> /tmp/at_alert.txt
echo "按用户统计:" >> /tmp/at_alert.txt
atq | awk '{print $5}' | sort | uniq -c >> /tmp/at_alert.txt
cat /tmp/at_alert.txt | mail -s "At任务详细报告" "$ALERT_EMAIL"
rm -f /tmp/at_alert.txt
fi
#!/bin/bash
# 自动清理已经过期的at任务
LOG_FILE="/var/log/at_cleanup.log"
echo "$(date): 开始清理at任务" >> "$LOG_FILE"
atq | while read line; do
job_id=$(echo "$line" | awk '{print $1}')
job_time=$(echo "$line" | awk '{print $2" "$3}')
# 将时间转换为时间戳
job_timestamp=$(date -d "$job_time" +%s 2>/dev/null)
now_timestamp=$(date +%s)
# 如果时间转换失败或任务已过期
if [ -z "$job_timestamp" ] || [ "$job_timestamp" -lt "$now_timestamp" ]; then
# 删除任务
atrm "$job_id"
echo " 删除任务 $job_id (时间: $job_time)" >> "$LOG_FILE"
fi
done
echo "$(date): 清理完成" >> "$LOG_FILE"
#!/bin/bash
# 检测是否有任务调度冲突(同一时间多个任务)
CONFLICT_THRESHOLD=5 # 同一时间最多允许的任务数
CONFLICT_LOG="/var/log/at_conflict.log"
echo "$(date): 检查at任务调度冲突" > "$CONFLICT_LOG"
# 按执行时间分组统计
atq | awk '{print $2" "$3}' | sort | uniq -c | while read count time; do
if [ "$count" -gt "$CONFLICT_THRESHOLD" ]; then
echo "冲突警告: 时间 $time 有 $count 个任务" >> "$CONFLICT_LOG"
# 列出冲突的任务
echo "冲突的任务列表:" >> "$CONFLICT_LOG"
atq | grep "$time" >> "$CONFLICT_LOG"
echo "" >> "$CONFLICT_LOG"
fi
done
#!/bin/bash
# 检查用户是否超过任务限额
MAX_JOBS_PER_USER=10
REPORT_FILE="/tmp/user_at_report.txt"
echo "用户at任务使用报告" > "$REPORT_FILE"
echo "生成时间: $(date)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 按用户统计任务数
atq | awk '{print $5}' | sort | uniq -c | sort -rn | while read count user; do
echo "用户: $user" >> "$REPORT_FILE"
echo " 任务数: $count" >> "$REPORT_FILE"
if [ "$count" -gt "$MAX_JOBS_PER_USER" ]; then
echo " ⚠️ 超过限额 ($MAX_JOBS_PER_USER)" >> "$REPORT_FILE"
# 列出该用户的所有任务
atq | grep " $user$" | head -5 | while read job; do
echo " $job" >> "$REPORT_FILE"
done
if [ "$count" -gt 15 ]; then
echo " ... 还有 $((count - 15)) 个任务" >> "$REPORT_FILE"
fi
fi
echo "" >> "$REPORT_FILE"
done
# 发送报告给管理员
cat "$REPORT_FILE" | mail -s "At任务用户统计" admin@example.com
#!/bin/bash
# 记录at任务执行历史(需要配合其他监控工具)
HISTORY_FILE="/var/log/at_history.log"
# 定期检查任务变化
PREV_COUNT_FILE="/tmp/at_prev_count.txt"
CURRENT_COUNT=$(atq | wc -l)
# 读取上一次的任务数
if [ -f "$PREV_COUNT_FILE" ]; then
PREV_COUNT=$(cat "$PREV_COUNT_FILE")
else
PREV_COUNT=0
fi
# 记录变化
if [ "$CURRENT_COUNT" -ne "$PREV_COUNT" ]; then
echo "$(date): 任务数变化 $PREV_COUNT -> $CURRENT_COUNT" >> "$HISTORY_FILE"
# 记录详细变化
if [ "$CURRENT_COUNT" -gt "$PREV_COUNT" ]; then
echo " 新增任务:" >> "$HISTORY_FILE"
# 这里可以添加逻辑来识别新增的任务
fi
fi
# 保存当前任务数
echo "$CURRENT_COUNT" > "$PREV_COUNT_FILE"
#!/bin/bash
# 在多台服务器间同步at任务状态(简化示例)
SERVERS=("server1.example.com" "server2.example.com" "server3.example.com")
CENTRAL_LOG="/var/log/central_at_status.log"
echo "=== 跨服务器at任务状态 ===" > "$CENTRAL_LOG"
echo "检查时间: $(date)" >> "$CENTRAL_LOG"
echo "" >> "$CENTRAL_LOG"
for SERVER in "${SERVERS[@]}"; do
echo "服务器: $SERVER" >> "$CENTRAL_LOG"
# 通过SSH获取远程服务器的atq输出
ssh "$SERVER" "atq 2>/dev/null || echo 'at服务未运行'" >> "$CENTRAL_LOG"
JOB_COUNT=$(ssh "$SERVER" "atq 2>/dev/null | wc -l")
echo " 任务数: $JOB_COUNT" >> "$CENTRAL_LOG"
echo "" >> "$CENTRAL_LOG"
done
A: 可能的原因:
sudo systemctl status atd# 检查atd服务
sudo systemctl status atd
# 以root用户查看所有任务
sudo atq
# 创建测试任务
echo "echo test" | at now + 1 minute
atq
A: 队列符号 = 表示该任务当前正在执行中。
# 查看正在执行的任务
atq | grep " = "
# 示例输出
# 15 2024-01-01 10:05 = username
# 这意味着任务15正在执行
# 一旦任务完成,该条目会从atq输出中消失
A: 使用 at -c 命令查看任务内容:
# 先用atq获取任务编号
atq
# 输出: 15 2024-01-01 10:05 a username
# 查看任务15的详细内容
at -c 15
# 查看命令部分(过滤掉环境变量设置)
at -c 15 | tail -20
# 查看特定行数
at -c 15 | head -50
A: 两者功能完全相同,atq 是 at -l 的别名:
# 两个命令的输出完全相同
atq
at -l
# 检查是否指向同一个程序
which atq
which at
# 实际上atq通常是一个符号链接
ls -l $(which atq)
在大多数系统中,atq 是 at 命令的符号链接。
A: 默认情况下,普通用户只能看到自己创建的at任务。root用户可以查看所有用户的任务。
# 普通用户只能看到自己的任务
whoami
atq
# root用户可以看到所有任务
sudo atq
# 查看特定用户的任务
sudo atq | grep username
# 权限由/etc/at.allow和/etc/at.deny文件控制