Bash移动.gz文件至S3前如何为文件名添加实例IP地址
故障原因
- 你用单引号包裹了
find -exec调用的子Bash代码块,外层主脚本定义的ip4变量属于父进程变量,默认不会传入子shell环境,子进程内无法读取到IP地址值 ${item/ip4}是Bash内置的字符串替换语法,作用是删除变量item中第一次出现的ip4字面字符串,完全不是拼接IP到文件名的写法,逻辑本身不符合需求- 原写法直接传入本地文件全路径给
s3 cp命令,会把本地目录结构同步到S3路径中,不符合常规日志备份的路径预期
修正后可直接运行的脚本
#!/bin/bash # 提取eth0网卡的IPv4地址 ip4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) find /home/user/tst/logs -name '*.gz' -exec bash -c ' # 读取传入的IP参数,剩余参数为find匹配到的文件列表 s3_ip="$1" shift for item do # 提取纯文件名,避免本地路径被带入S3存储路径 file_basename=$(basename "$item") # 拼接S3目标路径,格式为 IP_原文件名,可按需调整拼接规则 s3_target="s3://s3backups/tst/${s3_ip}_${file_basename}" aws s3 cp "$item" "$s3_target" if [[ $? -eq 0 ]]; then sudo rm -f "$item" fi done ' bash "$ip4" {} +
补充说明
- 传参逻辑:把外层获取到的
ip4值作为子Bash的第一个位置参数传入,子shell内先读取该IP值,再通过shift命令将IP参数移出位置参数列表,后续循环即可正常遍历find匹配到的所有文件 - 文件名格式可按需调整:如果需要把IP放在文件名后缀之前,可将S3目标路径的拼接规则改为
s3://s3backups/tst/${file_basename%.gz}_${s3_ip}.gz,最终S3内的文件名为原日志名_IP地址.gz - 所有变量均添加双引号包裹,兼容文件名含空格、特殊字符的场景,避免执行报错
rm命令添加-f参数,避免删除文件时出现不必要的交互提示
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

