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

Elixir中System.cmd执行带通配符的rm命令失败问题

解决Elixir中批量删除带通配符PNG文件的问题

我懂你碰到的麻烦了——用System.cmd("rm", ["/path/to/dir/" <> uuid <> "-frames-*.png"])删除文件总是失败,核心问题其实是Elixir的System.cmd默认不会通过shell执行命令,你写的*通配符根本不会被解析展开,rm会把整个带*的字符串当成一个单独的文件名去找,自然找不到对应的文件。

下面给你几个靠谱的解决方案,按安全性和易用性排序:

方案1:用Elixir原生文件API(最安全推荐)

直接用Elixir的Path.wildcard匹配所有符合模式的文件,再逐个删除,完全不需要依赖shell,也避免了shell注入的风险(如果uuid是用户输入的话这点尤其重要):

# 匹配所有符合格式的PNG文件
files_to_delete = Path.wildcard("/path/to/dir/#{uuid}-frames-*.png")

# 逐个删除,File.rm会返回{:ok, _}或{:error, reason},可以按需处理结果
Enum.each(files_to_delete, fn file ->
  case File.rm(file) do
    :ok -> IO.puts("成功删除文件:#{file}")
    {:error, reason} -> IO.puts("删除文件失败 #{file}:#{inspect(reason)}")
  end
end)

# 如果想强制删除(忽略不存在的文件或权限问题时直接抛出异常),可以用File.rm!/1
# Enum.each(files_to_delete, &File.rm!/1)

方案2:让System.cmd通过shell执行

如果你更习惯用shell命令,可以给System.cmd加上shell: true选项,这样shell会帮你展开通配符。但要注意:如果uuid包含特殊字符(比如空格、引号)或者来自不可信的用户输入,这种方式可能会有shell注入风险,一定要确保uuid是安全的(比如是标准UUID格式,没有特殊字符):

System.cmd("rm", ["/path/to/dir/#{uuid}-frames-*.png"], shell: true)

方案3:先匹配文件再传给rm命令

和方案1类似,但用rm批量删除,适合需要一次性传递所有文件给rm的场景:

files = Path.wildcard("/path/to/dir/#{uuid}-frames-*.png")
# 如果文件列表为空,rm会报错,所以可以加个判断避免无意义的调用
if length(files) > 0 do
  System.cmd("rm", files)
end

额外排查点

如果还是失败,可以检查这几点:

  • 确认/path/to/dir/路径正确,程序拥有该目录的读写权限
  • 确认uuid拼接后路径正确,比如有没有多了或少了斜杠
  • 检查服务器上的文件是否真的存在,类Unix系统要注意文件名大小写区分问题

内容的提问来源于stack exchange,提问作者Kulix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:34:54