如何在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
相关产品推荐
相关产品推荐

