You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MariaDB表更新/插入行后执行指定Bash脚本

搞定MariaDB表更新/插入后自动运行Bash脚本的方案

我来给你捋一套靠谱的实现思路,毕竟MariaDB触发器本身没法直接跑shell脚本,得绕个小弯子,但操作起来不难~

核心逻辑

咱们用「触发器写信号 + 后台脚本监听」的组合:触发器在表更新/插入时往一个管道里写标记,后台脚本盯着这个管道,一看到信号就自动执行你要的脚本。


第一步:先整个通信管道(FIFO)

先建个命名管道,让MariaDB和监听脚本能传话:

mkfifo /tmp/mariadb_trigger.fifo
chown mysql:mysql /tmp/mariadb_trigger.fifo  # 得让MariaDB有权限往里面写东西

第二步:给MariaDB加触发器

假设你的目标表叫your_target_table,分两种场景加触发器:

场景1:表更新后触发脚本

DELIMITER //
CREATE TRIGGER after_table_update
AFTER UPDATE ON your_target_table
FOR EACH ROW
BEGIN
    -- 往管道里写个"UPDATE"标记,告诉监听脚本是更新事件
    SELECT 'UPDATE' INTO OUTFILE '/tmp/mariadb_trigger.fifo';
END //
DELIMITER ;

场景2:插入行后触发脚本

DELIMITER //
CREATE TRIGGER after_table_insert
AFTER INSERT ON your_target_table
FOR EACH ROW
BEGIN
    -- 写个"INSERT"标记对应插入事件
    SELECT 'INSERT' INTO OUTFILE '/tmp/mariadb_trigger.fifo';
END //
DELIMITER ;

划重点:如果MariaDB的secure_file_priv限制了文件路径,得先改配置!
打开my.cnf(或my.ini),加一行:

secure_file_priv = /tmp

改完重启MariaDB服务才生效哦。


第三步:写个后台监听脚本

整个trigger_listener.sh脚本,让它一直盯着管道,收到信号就跑你的目标脚本:

#!/bin/bash
FIFO="/tmp/mariadb_trigger.fifo"

# 先检查管道有没有,没有就重建
if [ ! -p "$FIFO" ]; then
    mkfifo "$FIFO"
    chown mysql:mysql "$FIFO"
fi

# 死循环监听,一有信号就干活
while true; do
    if read -r signal < "$FIFO"; then
        echo "$(date) 收到触发信号: $signal,开始执行目标脚本..." >> /var/log/trigger_listener.log
        # 把下面的路径换成你实际的目标脚本路径,比如/tmp/your_script.sh
        /path/to/your/target_script.sh
    fi
done

给脚本加执行权限:

chmod +x trigger_listener.sh

第四步:优化你给的目标脚本

我把你提供的脚本调整了下,避免空格文件名、循环逻辑的坑:

#!/bin/bash
# 连接数据库执行SQL生成CSV(建议用~/.my.cnf存密码,别明文写在这!)
mysql -u{user} -p{passwd} {database} < req_mp3.sql

# 遍历/tmp下的CSV文件,处理带空格的文件名也没问题
find /tmp -maxdepth 1 -type f -name "*csv" | while read -r csv_file; do
    # 逐行读CSV,按|分割字段,处理带空格的行
    while IFS="|" read -r mp3 _ id; do
        # 用ffmpeg拿音频时长,优化了管道命令
        time=$(ffmpeg -i "/tracks/${mp3}" 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F"00:" '{print $2}' | awk -F"." '{print $1}')
        # 这里可以加你后续要做的操作,比如把时长和ID存回数据库
        echo "处理文件: $mp3,ID: $id,时长: $time" >> /var/log/target_script.log
    done < "$csv_file"
done

小贴士:别在命令行明文写数据库密码!可以在~/.my.cnf里加:

[client]
user=你的用户名
password=你的密码

然后给文件加权限chmod 600 ~/.my.cnf,这样mysql命令会自动读这个文件的认证信息,安全多了。


第五步:让监听脚本常驻后台

两种方法,推荐用systemd服务,稳得一批:

方法1:临时用nohup跑

nohup ./trigger_listener.sh > /var/log/trigger_listener.log 2>&1 &

方法2:配置成systemd服务(开机自启)

创建/etc/systemd/system/mariadb-trigger-listener.service文件:

[Unit]
Description=MariaDB触发器监听服务
After=mariadb.service

[Service]
Type=simple
User=root
ExecStart=/path/to/your/trigger_listener.sh
Restart=always  # 挂了自动重启
RestartSec=5

[Install]
WantedBy=multi-user.target

然后执行命令启用服务:

systemctl daemon-reload
systemctl enable mariadb-trigger-listener.service
systemctl start mariadb-trigger-listener.service

测试一下

手动往your_target_table插一行或者改一行数据,然后看/var/log/trigger_listener.log有没有日志,再检查CSV生成、ffmpeg处理的结果,没问题就搞定啦!

内容的提问来源于stack exchange,提问作者lejuste

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:49:26