cal 是Linux系统中用于显示日历的命令行工具。它可以显示当前月份的日历,也可以显示指定月份或年份的日历。cal命令简单实用,特别适合在服务器环境下快速查看日期信息,无需离开终端界面。
cal [选项] [[月份] 年份]
| 选项 | 说明 |
|---|---|
-1, --one |
显示单月日历(默认) |
-3, --three |
显示前一个月、当前月、下一个月的日历 |
-s, --sunday |
以周日作为一周的第一天 |
-m, --monday |
以周一作为一周的第一天 |
-j, --julian |
显示儒略历(从1月1日开始的天数) |
-y, --year |
显示整年的日历 |
-Y, --twelve |
显示未来12个月的日历 |
-w, --week |
显示周数(ISO 8601标准) |
-n 月数 |
显示指定月数的日历 |
-A 月数 |
在当前日历后显示指定月数的日历 |
-B 月数 |
在当前日历前显示指定月数的日历 |
-h, --help |
显示帮助信息 |
-V, --version |
显示版本信息 |
显示当前月份的日历:
# 显示当前月份日历(默认)
cal
# 显示当前月份(显式使用-1选项)
cal -1
# 示例输出:
# December 2024
# Su Mo Tu We Th Fr Sa
# 1 2 3 4 5 6 7
# 8 9 10 11 12 13 14
# 15 16 17 18 19 20 21
# 22 23 24 25 26 27 28
# 29 30 31
显示前一个月、当前月和下一个月的日历:
# 显示三个月的日历
cal -3
# 使用长选项
cal --three
# 示例输出:
# November 2024 December 2024 January 2025
# Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
# 1 2 1 2 3 4 5 6 7 1 2 3 4
# 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
# 10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
# 17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
# 24 25 26 27 28 29 30 29 30 31 26 27 28 29 30 31
显示指定月份和年份的日历:
# 显示2024年12月的日历
cal 12 2024
# 显示当前年份的7月日历
cal 7
# 显示历史上的重要日期
cal 7 1969 # 阿波罗11号登月
cal 1 2000 # 新千年
cal 9 2001 # 9/11事件
显示指定年份的全部月份日历:
# 显示当前年份的完整日历
cal -y
# 显示指定年份的完整日历
cal -y 2025
cal 2025
# 示例输出(部分):
# 2025
#
# January February March
# Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
# 1 2 3 4 1 1
# 5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8
# 12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15
# 19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22
# 26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29
# 30 31
设置一周的第一天为周日或周一:
# 以周日作为一周的第一天(默认)
cal -s
cal --sunday
# 以周一作为一周的第一天
cal -m
cal --monday
# 示例输出(周一作为第一天):
# December 2024
# Mo Tu We Th Fr Sa Su
# 1
# 2 3 4 5 6 7 8
# 9 10 11 12 13 14 15
# 16 17 18 19 20 21 22
# 23 24 25 26 27 28 29
# 30 31
显示儒略历(从1月1日开始计数的天数):
# 显示当前月份的儒略历
cal -j
# 显示2024年12月的儒略历
cal -j 12 2024
# 示例输出:
# December 2024
# Su Mo Tu We Th Fr Sa
# 336 337 338 339 340 341 342
# 343 344 345 346 347 348 349
# 350 351 352 353 354 355 356
# 357 358 359 360 361 362 363
# 364 365 366
# 显示周数(ISO 8601标准)
cal -w
# 或
cal --week
# 显示未来12个月的日历
cal -Y
cal --twelve
# 显示指定数量的月份
cal -n 6 # 显示6个月
cal -A 2 # 显示当前月和后2个月
cal -B 1 -A 2 # 显示前1个月、当前月和后2个月
# 显示包含周数的三个月日历
cal -3 -w
# 组合选项:显示以周一为起始的三个月日历
cal -m -3
# 显示当前年份的儒略历
cal -j -y
# 显示2025年以周日为起始的日历
cal -s 2025
# 显示特定月份范围
seq 1 12 | xargs -I {} cal {} 2024 # 显示2024年所有月份
# 在脚本中获取特定日期是星期几
cal 12 2024 | awk 'NR>2{print $1}' | grep -n "25" | head -1
cal命令支持多种语言环境下的月份名称:
# 查看当前语言环境
echo $LANG
# 设置不同语言环境查看日历
LANG=zh_CN.UTF-8 cal # 中文
LANG=ja_JP.UTF-8 cal # 日文
LANG=fr_FR.UTF-8 cal # 法语
LANG=de_DE.UTF-8 cal # 德语
LANG=es_ES.UTF-8 cal # 西班牙语
# 临时设置英文环境
LANG=C cal
cal命令支持显示公元1年到9999年的日历:
# 显示最早年份的日历
cal 1
# 输出:公元1年1月
# 显示最晚年份的日历
cal 9999
# 输出:公元9999年12月
# 显示历史重要年份
cal 1066 # 诺曼征服英格兰
cal 1492 # 哥伦布发现新大陆
cal 1776 # 美国独立宣言
cal 1914 # 第一次世界大战开始
cal 1945 # 第二次世界大战结束
#!/bin/bash
# 脚本1:检查今天是否是周五
TODAY=$(date +%d)
if cal | grep -E "(^| )$TODAY( |$)" | grep -q "Fr"; then
echo "今天是周五!🎉"
else
echo "今天不是周五。"
fi
# 脚本2:计算某个月有多少天
get_month_days() {
local month=$1
local year=$2
cal "$month" "$year" | awk 'NF {DAYS=$NF} END {print DAYS}'
}
# 使用示例
days_in_dec=$(get_month_days 12 2024)
echo "2024年12月有 $days_in_dec 天"
# 脚本3:生成月历报告
generate_calendar_report() {
echo "=== 月历报告 ==="
echo "生成时间: $(date)"
echo ""
cal -3
echo ""
echo "当前日期: $(date '+%Y年%m月%d日 %A')"
}
# 保存报告到文件
generate_calendar_report > /tmp/calendar_report.txt
# 脚本4:查找特定日期的星期几
find_weekday() {
local day=$1
local month=$2
local year=$3
cal "$month" "$year" | awk -v day="$day" '
NR>2 {
for(i=1;i<=NF;i++) {
if($i == day) {
# 获取列索引对应的星期
if(NR==3) {print "星期" (i==1?"日":i==2?"一":i==3?"二":i==4?"三":i==5?"四":i==6?"五":"六")}
exit
}
}
}
'
}
# 使用示例
weekday=$(find_weekday 25 12 2024)
echo "2024年圣诞节是: $weekday"
# 显示今天在日历中的位置
today=$(date +%d)
cal | sed "s/\(^\|[[:space:]]\)\($today\)\([[:space:]]\|$\)/\1**\2**\3/"
# 显示当前月份并高亮今天
cal | awk -v today="$(date +%d)" '{
for(i=1;i<=NF;i++) {
if($i == today && NR>2) {
$i = "\033[1;31m" $i "\033[0m"
}
}
print
}'
# 使用日期计算
echo "30天后的日期:"
date -d "+30 days" "+%Y-%m-%d"
cal $(date -d "+30 days" "+%m %Y")
# 显示带有节假日标记的日历(需要自定义)
mark_holiday() {
cal | sed -e 's/ 25 /🎄/' -e 's/ 1 /🎆/' -e 's/ 14 /💝/'
}
# 显示当月的工作日数量
count_weekdays() {
cal | awk '
NR>2 {
for(i=1;i<=NF;i++) {
if($i ~ /^[0-9]+$/) {
# 假设周一至周五是工作日(周一为第一天时)
if(i>=2 && i<=6) count++
}
}
}
END {print "本月工作日天数:", count}'
}
# 显示当月的周末日期
get_weekends() {
echo "本月周末日期:"
cal | awk '
NR>2 {
for(i=1;i<=NF;i++) {
if($i ~ /^[0-9]+$/) {
# 假设周六和周日是周末
if(i==1 || i==7) printf "%s ", $i
}
}
if(NR>2) print ""
}'
}
cal [月份] [年份],如果只提供一个数字参数,cal会将其解释为年份cal [年份] [月份],但建议使用标准语法cal命令的历史可以追溯到UNIX系统的早期版本。一些有趣的日历事实:
# 1. cal命令不存在
# 检查是否安装
which cal
# 安装(如果需要)
# Ubuntu/Debian: sudo apt-get install bsdmainutils
# RHEL/CentOS: sudo yum install util-linux
# 2. 显示乱码
# 检查语言环境
locale
# 设置UTF-8编码
export LANG=en_US.UTF-8
# 3. 月份或年份参数无效
# 检查参数范围
cal 13 2024 # 错误:月份无效
cal 12 10000 # 错误:年份超出范围
# 4. 输出格式问题
# 使用col命令处理格式
cal | col -b # 去除退格和特殊字符
# 5. 获取特定版本的cal
cal --version
# 或
whatis cal