在本项目中,因为Hugo以Docker的方式进行部署,所以想要发布文章在操作流程上可能有些繁琐复杂而不人性化,因此我们可以编写Shell脚本来将这个流程简化

一、 原本发布 Hugo 文章的完整流程

当前目录结构类似:

/root/HybridBlog

├── Dockerfile
├── Jenkinsfile
└── blog
    ├── content
    │   └── posts
    │       ├── devops-platform.md
    │       └── xxx.md
    ├── themes
    │   └── PaperMod
    ├── hugo.toml
    └── public

所以以后发布文章需要修改 Git 仓库里的 blog/content/posts


1.1 创建新文章

进入项目目录:

cd /root/HybridBlog

进入 blog:

cd blog

使用 Harbor 里的 Hugo 镜像生成文章:

docker run --rm \
-v $(pwd):/src \
-w /src \
192.168.10.20/hybridblog/hugo:exts \
hugo new content posts/4_Harbor_registry_deployment.md

成功:

Content "/src/content/posts/4_Harbor_registry_deployment.md" created

1.2 编辑文章

例如:

vim content/posts/4_Harbor_registry_deployment.md

添加固定格式:

如:

+++
title = "Jenkins CI 持续集成平台部署"
date = 2026-07-24T10:40:00+08:00
draft = false
tags = [
    "Jenkins",
    "CI",
    "DevOps"
]
categories = [
    "云计算"
]
+++

1.3 本地测试

使用 Harbor 中保存的 Hugo 镜像:

docker run --rm \
-v $(pwd):/src \
-p 1313:1313 \
-w /src \
192.168.10.20/hybridblog/hugo:exts \
hugo server --bind 0.0.0.0

输出:

Web Server is available at
http://localhost:1313/

浏览:

http://192.168.10.10:1313

尝试构建镜像确认没有报错

docker run --rm \
-v $(pwd):/src \
-w /src \
192.168.10.20/hybridblog/hugo:exts \
hugo --minify

1.4 提交 Git

回到项目根目录:

cd /root/HybridBlog

查看:

git status

应该看到:

modified:
 blog/content/posts/4_Harbor_registry_deployment.md

添加:

git add .

提交:

git commit -m "添加文章: Harbor registry deployment article"

推送:

git push origin main

二、将其Shell脚本化

进入项目目录:

cd /root/HybridBlog

新建并编写脚本文件:

2.1 发布新文章:

[root@devops HybridBlog]# vim publish-post.sh
#!/bin/bash
set -e

# ====================== 配置区(根据你的环境修改) ======================
PROJECT_DIR="/root/HybridBlog"          # 项目根目录
BLOG_DIR="$PROJECT_DIR/blog"            # Hugo 博客目录
HUGO_IMAGE="192.168.10.20/hybridblog/hugo:exts"  # Harbor 中的 Hugo 镜像
POSTS_DIR="content/posts"               # 文章存放路径
GIT_BRANCH="main"                       # Git 推送分支
# ======================================================================

# 颜色输出
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
NC="\033[0m"

# 1. 参数检查与输入处理
if [ $# -lt 2 ]; then
    echo -e "${YELLOW}用法: $0 文章文件名.md \"文章标题\" [标签1,标签2] [分类]${NC}"
    echo -e "示例: $0 5_wireguard_setup.md \"WireGuard 组网部署教程\" \"WireGuard,运维\" \"云计算\""
    exit 1
fi

POST_FILE="$1"
POST_TITLE="$2"
POST_TAGS="${3:-"DevOps"}"
POST_CATEGORY="${4:-"云计算"}"
POST_PATH="$BLOG_DIR/$POSTS_DIR/$POST_FILE"

# 2. 前置检查
cd "$PROJECT_DIR" || { echo -e "${RED}错误: 项目目录不存在${NC}"; exit 1; }

if [ -f "$POST_PATH" ]; then
    echo -e "${RED}错误: 文章 $POST_FILE 已存在${NC}"
    exit 1
fi

# 3. 使用 Hugo 镜像创建新文章
echo -e "${GREEN}[1/5] 正在创建新文章...${NC}"
docker run --rm \
    -v "$BLOG_DIR":/src \
    -w /src \
    "$HUGO_IMAGE" \
    hugo new "$POSTS_DIR/$POST_FILE" > /dev/null

# 4. 覆盖文章头部元数据(固定格式)
POST_DATE=$(date "+%Y-%m-%dT%H:%M:%S+08:00")

# 把标签字符串转成数组格式
TAG_ARRAY=$(echo "$POST_TAGS" | awk -F',' '{for(i=1;i<=NF;i++) printf "    \"%s\",\n", $i}')

cat > "$POST_PATH" << EOF
+++
title = "$POST_TITLE"
date = $POST_DATE
draft = false
tags = [
$TAG_ARRAY
]
categories = [
    "$POST_CATEGORY"
]
+++

EOF

echo -e "${GREEN}[2/5] 文章头部已自动填充${NC}"
echo -e "${YELLOW}即将打开 Vim 编辑文章正文,编辑完成输入 :wq 保存退出,脚本将自动继续${NC}"
sleep 1
vim "$POST_PATH"

# 5. Hugo 构建校验
echo -e "${GREEN}[3/5] 正在执行 Hugo 构建校验...${NC}"
docker run --rm \
    -v "$BLOG_DIR":/src \
    -w /src \
    "$HUGO_IMAGE" \
    hugo --minify > /dev/null
echo -e "${GREEN}构建成功,无语法错误${NC}"

# 6. Git 提交并推送
echo -e "${GREEN}[4/5] 正在提交 Git...${NC}"
cd "

为脚本文件增加执行权限:

chmod +x ./publish-post.sh

在此之后只需执行脚本并按照标准格式输入便可发布新文章。


同理,我们可以编写修改文章与删除已发布文章的脚本

2.2 修改文章:

#!/bin/bash
set -e

# ====================== 配置区(与新建脚本保持一致即可) ======================
PROJECT_DIR="/root/HybridBlog"          # 项目根目录
BLOG_DIR="$PROJECT_DIR/blog"            # Hugo 博客目录
HUGO_IMAGE="192.168.10.20/hybridblog/hugo:exts"  # Harbor 中的 Hugo 镜像
POSTS_DIR="content/posts"               # 文章存放路径
GIT_BRANCH="main"                       # Git 推送分支
# ======================================================================

# 颜色输出
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
NC="\033[0m"

# 1. 参数检查
if [ $# -lt 1 ]; then
    echo -e "${YELLOW}用法: $0 文章文件名.md [自定义提交信息]${NC}"
    echo -e "示例: $0 4_Harbor_registry_deployment.md \"更新Harbor部署步骤说明\""
    echo -e "目前仓库中已有文章:"
    ls "$BLOG_DIR/$POSTS_DIR"
   exit 1
fi

POST_FILE="$1"
COMMIT_MSG="${2:-更新文章: $POST_FILE}"
POST_PATH="$BLOG_DIR/$POSTS_DIR/$POST_FILE"

# 2. 前置检查:文件必须存在
cd "$PROJECT_DIR" || { echo -e "${RED}错误: 项目目录不存在${NC}"; exit 1; }

if [ ! -f "$POST_PATH" ]; then
    echo -e "${RED}错误: 文章 $POST_FILE 不存在${NC}"
    echo -e "${YELLOW}请确认文件名是否正确,路径: $POSTS_DIR/$POST_FILE${NC}"
    exit 1
fi

# 3. 打开 Vim 编辑文章
echo -e "${GREEN}[1/4] 正在打开文章进行编辑...${NC}"
echo -e "${YELLOW}编辑完成输入 :wq 保存退出,脚本将自动继续${NC}"
sleep 1
vim "$POST_PATH"

# 4. Hugo 构建校验
echo -e "${GREEN}[2/4] 正在执行 Hugo 构建校验...${NC}"
docker run --rm \
    -v "$BLOG_DIR":/src \
    -w /src \
    "$HUGO_IMAGE" \
    hugo --minify > /dev/null
echo -e "${GREEN}构建成功,无语法错误${NC}"

# 5. Git 提交
echo -e "${GREEN}[3/4] 正在提交 Git...${NC}"
cd "$PROJECT_DIR"
git add .

# 无变更时友好提示,不报错
git commit -m "$COMMIT_MSG" || {
    echo -e "${YELLOW}检测到文章内容无修改,跳过提交${NC}"
    exit 0
}

# 6. 推送到 Gitea
echo -e "${GREEN}[4/4] 正在推送到 Gitea...${NC}"
git push origin "$GIT_BRANCH"

echo -e "\n${GREEN}✅ 更新完成!文章已推送至 Gitea 仓库 ${GIT_BRANCH} 分支${NC}"

2.3 删除已发布文章:

#!/bin/bash
set -e

# ====================== 配置区(与新建/编辑脚本保持完全一致) ======================
PROJECT_DIR="/root/HybridBlog"          # 项目根目录
BLOG_DIR="$PROJECT_DIR/blog"            # Hugo 博客目录
HUGO_IMAGE="192.168.10.20/hybridblog/hugo:exts"  # Harbor 中的 Hugo 镜像
POSTS_DIR="content/posts"               # 文章存放路径
GIT_BRANCH="main"                       # Git 推送分支
# ======================================================================

# 颜色输出
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
NC="\033[0m"

# 1. 参数检查
if [ $# -lt 1 ]; then
    echo -e "${YELLOW}用法: $0 文章文件名.md [自定义提交信息]${NC}"
    echo -e "示例: $0 4_Harbor_registry_deployment.md \"移除过时的Harbor部署文章\""
    echo -e "目前仓库中已有文章:"
    ls "$BLOG_DIR/$POSTS_DIR" 
    exit 1
fi

POST_FILE="$1"
COMMIT_MSG="${2:-删除文章: $POST_FILE}"
POST_PATH="$BLOG_DIR/$POSTS_DIR/$POST_FILE"

# 2. 前置检查:文件必须存在
cd "$PROJECT_DIR" || { echo -e "${RED}错误: 项目目录不存在${NC}"; exit 1; }

if [ ! -f "$POST_PATH" ]; then
    echo -e "${RED}错误: 文章 $POST_FILE 不存在${NC}"
    echo -e "${YELLOW}请确认文件名是否正确,路径: $POSTS_DIR/$POST_FILE${NC}"
    exit 1
fi

# 3. 二次确认(防误删)
echo -e "${RED}⚠  即将永久删除文章: $POST_FILE${NC}"
echo -e "${YELLOW}文件路径: $POST_PATH${NC}"
read -p "确认删除请输入 yes,其他输入将取消操作: " confirm

if [ "$confirm" != "yes" ]; then
    echo -e "${YELLOW}已取消删除操作${NC}"
    exit 0
fi

# 4. 执行删除
echo -e "${GREEN}[1/4] 正在删除文章文件...${NC}"
rm -f "$POST_PATH"
echo -e "${GREEN}文件已删除${NC}"

# 5. Hugo 构建校验(删除后验证站点是否正常)
echo -e "${GREEN}[2/4] 正在执行 Hugo 构建校验...${NC}"
docker run --rm \
    -v "$BLOG_DIR":/src \
    -w /src \
    "$HUGO_IMAGE" \
    hugo --minify > /dev/null
echo -e "${GREEN}构建成功,站点无异常${NC}"

# 6. Git 提交
echo -e "${GREEN}[3/4] 正在提交 Git...${NC}"
cd "$PROJECT_DIR"
git add .
git commit -m "$COMMIT_MSG"

# 7. 推送到 Gitea
echo -e "${GREEN}[4/4] 正在推送到 Gitea...${NC}"
git push origin "$GIT_BRANCH"

echo -e "\n${GREEN}✅ 删除完成!变更已推送至 Gitea 仓库 ${GIT_BRANCH} 分支${NC}"