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[@]}",要传数组所有元素;函数传数组要用 "$@" 重新接收所有元素,然后再处理数组。

相关推荐
其实防守也摸鱼2 小时前
GDB安装与配置(保姆级教程)【Linux、Windows系统】
linux·运维·windows·命令模式·工具·虚拟机·调试
NoSi EFUL7 小时前
MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
android·数据库·mysql
柴米油盐那点事儿8 小时前
python+mysql+bootstrap条件搜索分页
python·mysql·flask·bootstrap
AC赳赳老秦8 小时前
OpenClaw二次开发实战:编写专属办公自动化技能,适配个性化需求
linux·javascript·人工智能·python·django·测试用例·openclaw
Devin~Y8 小时前
大厂Java面试实录:Spring Boot/Cloud、Kafka、Redis、K8s 与 Spring AI(RAG/Agent)三轮连环问
java·spring boot·redis·mysql·spring cloud·kafka·kubernetes
mounter6259 小时前
【内核新动向】告别物理槽位束缚:深度解析 Linux Virtual Swap Space 机制
linux·内存管理·kernel·swap·virtual swap
handler019 小时前
从零实现自动化构建:Linux Makefile 完全指南
linux·c++·笔记·学习·自动化
chenxu98b10 小时前
MySQL如何执行.sql 文件:详细教学指南
数据库·mysql
2023自学中10 小时前
i.MX6ULL 板子的完整启动流程图(从上电 → 用户空间)
linux·嵌入式
闫利朋10 小时前
Ubuntu 24.04 桌面安装向日葵完整指南
linux·运维·ubuntu