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

SUSE Linux 15下Shell脚本无法正确收集符合条件的文件名至变量的问题求助

SUSE Linux 15下Shell脚本无法正确收集符合条件的文件名至变量的问题求助

嘿,我一眼就看出你遇到的是Shell脚本里非常典型的子shell变量作用域问题!先给你解释清楚原因,再给你几个靠谱的解决方案。

问题根源

你用了find ... | while read ...这种管道写法,在Bash里,管道两端的命令都会在独立的子shell中运行。也就是说,你的while循环是在子shell里执行的,循环中对DESTINATIONS变量的所有修改,都只会作用于子shell里的变量副本,不会传递回父shell。所以当循环结束后,父shell里的DESTINATIONS变量其实根本没被正确更新,这就是为什么你只能看到一个文件名的原因。

另外还有个小细节:你要筛选的是“过去24小时内修改的文件”,但你的find用了-mtime -30(这是找30天内修改的文件),应该改成-mtime -1才符合你的需求哦。

解决方案1:用重定向替代管道(避免子shell)

把管道换成进程替换的重定向写法,这样while循环就会在父shell里执行,变量修改就能生效了:

DESTINATIONS="main_crontab"
# 用< <(...)替代管道,让while在父shell运行
while read -d $'\0' file
do  
    DESTINATIONS+=" ${file}"
done < <(find . -name "sample_file_*" -type f -mtime -1 -print0)
echo ${DESTINATIONS}

解决方案2:用数组存储文件名(更安全,适配带空格的文件名)

如果你的文件名可能包含空格或特殊字符,用字符串拼接变量很容易出问题,推荐用数组来存储:

# 初始化数组,包含初始值"main_crontab"
DESTINATIONS=("main_crontab")
while read -d $'\0' file
do  
    DESTINATIONS+=("$file")
done < <(find . -name "sample_file_*" -type f -mtime -1 -print0)
# 打印数组所有元素,注意用[@]和双引号
echo "${DESTINATIONS[@]}"

解决方案3:直接将find结果赋值给数组(简化写法)

如果确定文件名没有空格,也可以直接把find的结果赋值给数组,写法更简洁:

DESTINATIONS=("main_crontab" $(find . -name "sample_file_*" -type f -mtime -1))
echo "${DESTINATIONS[@]}"

按照上面的方法修改后,就能正确收集到所有符合条件的文件名啦!

备注:内容来源于stack exchange,提问作者Sanjay Surve

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 11:39:38