Shell脚本中连接数据库查询数据报错 “No such file or directory“以及函数传参数组

Shell脚本中连接数据库查询数据报错 "No such file or directory"以及函数传参数组


前言

业务要求,编写一个Shell脚本,目的是定时从 MySQL 数据库中拉取业务数据,填入 CSV 报表中,并每日凌晨定时推送到远程平台。

在脚本调试过程中遇到了几个问题(Bash语法坑),好久不写Shell了生疏了......

问题1: 执行mysql命令,报错"No such file or directory"

报错

脚本中定义了一个数组用来存放 MySQL 的连接命令和参数,但在执行时报错:

sh 复制代码
# 第一种
MYSQL_CONN='/path/to/mysql -uuser -ppassword -S /tmp/mysql.sock dbname'
# ... 省略中间逻辑 ...
"${MYSQL_CONN}" -e "${sql}"

# 第二种
MYSQL_CONN=(/path/to/mysql -uuser -ppassword -S /tmp/mysql.sock dbname)
# ... 省略中间逻辑 ...
"${MYSQL_CONN[*]}" -e "${sql}"

原因分析

第一种因为我的password里特殊字符如@$符号,如mysql -uuser -p"passw@rd",shell 分词混乱会把密码分割开导致命令执行失败;

从网上查询的第二种方法,我明明 ls 看了,/path/to/mysql 这个文件是绝对存在的,为什么 Shell 还是说找不到文件?

问题的根源在于 ${MYSQL_CONN[*]} 中的这个 *
在 Bash 中,"${arr\*}" 会把数组中的所有元素合并成一个单一的字符串,中间默认用空格连接。Shell 在执行时,会试图去文件系统中寻找一个文件名叫 "mysql -uuser -ppassword..." 的文件。这当然找不到!文件名里怎么可能有 -u 这种参数呢?

解决方案

将 * 改为 @。"${arr@}" 会将数组元素展开为独立的参数,保留参数之间的分隔。这样 Shell 就会正确理解:第一个元素是命令,后面的元素是参数。

sh 复制代码
"${MYSQL_CONN[@]}" -e "${sql}"

问题2: mysql的静默输出

问题

发MySQL 默认返回的结果带漂亮的表格边框,首先想到使用grep、awk等工具去处理

sh 复制代码
+------------------+
| count(username)  |
+------------------+
|                2 |
+------------------+

解决方案

不需要用 grep 或 awk 去切分字符串,直接利用 MySQL 自带的参数:

-N:不显示列头(Header)。

-s:静默模式(Silent),去掉边框线条。

问题3 函数的参数是数组,调用问题

问题

sh 复制代码
fun_c(){
    local para=$1
}
arr=(a,b)
fun_c $arr

在调用函数的时候,发现只有a的处理逻辑,b一直未处理。

原因分析

调用时:$arr 默认只取数组的第一个元素。

接收时:local para=$1 只读取了第一个参数。

解决方案

必须显式地展开数组,并在函数内部用 $@ 重新接收。

sh 复制代码
fun_c(){
# 将传入的所有参数重新组装成数组
    local para=("$@")
    for i in ${para[@]}
}

arr=(a,b)
# 调用时:使用 [@] 并加引号
fun_c "${arr[@]}"

总结

原来一直以为${arr[@]}${arr[*]}是一样的含义,这次发现完全不同,数组展开永远优先使用 "${arr[@]}"。

此外,函数传参传数组要 "${arr[@]}",要传数组所有元素;函数传数组要用 "$@" 重新接收所有元素,然后再处理数组。

相关推荐
Yana.nice12 小时前
Linux 只保留 30 天内日志(find命令删除日志文件)
linux·运维·chrome
Database_Cool_13 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
Database_Cool_14 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
姜太小白15 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
DFT计算杂谈16 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
liuxiaowei316 小时前
【绝版教程】新版MySQL DBA高级实战进阶班 MySQL8.0 姜承尧-腾讯数据库总监
数据库·mysql·dba
Zhang~Ling17 小时前
从 fopen 到 struct file:从零开始拆解 Linux 文件 I/O
linux·运维·服务器
DeeplyMind17 小时前
Linux 深入 per-VMA lock:Linux 缺页路径如何摆脱 mmap_lock
linux·per-vma lock
爱写代码的森17 小时前
蒙三方库 | harmony-utils之FileUtil文件重命名与属性查询详解
linux·运维·服务器·华为·harmonyos·鸿蒙·huawei
XMAIPC_Robot18 小时前
软硬协同实时控制|RK3588业务调度+FPGA硬件时序,ethercat实现半导体设备微秒级响应(125us)
linux·arm开发·人工智能·fpga开发