我有一个elixir程序,需要以编程方式删除可变数量的PNG文件。
/path/to/dir/<uuid>-frames-001.png
/path/to/dir/<uuid>-frames-002.png
/path/to/dir/<uuid>-frames-003.png
等
当然,我已经提出了以下elixir代码来删除这些文件。
System.cmd("rm", ["/path/to/dir/" <> uuid <> "-frames-*.png"])
我已经看到上面的代码以多种方式失败了。首先,我在服务器上运行它并看到以下stacktrace:
/bin/rm: cannot remove '/path/to/dir/<uuid>-frames-*.png': No such file or directory
我还在控制台会话上运行此代码并看到完全相同的输出。
如果我在bash会话中运行以下命令,它可以正常工作!
rm /path/to/dir/<uuid>-frames-*.png
它返回0
错误代码并删除预期的文件。似乎elixir将*
解释为文字字符,而不是执行预期的通配符删除。知道怎么做到这一点?谢谢!
P.S。
显然,<uuid>
是一个实际的uuid,因此不应该从字面上解释这个问题的范围。
答案 0 :(得分:4)
json_decode($yourJsonVariable->pricing->in, true);
之类的通配符由shell扩展,而不是*
。您的命令只会删除名为rm
的文件。
您可以通过将命令传递给/path/to/dir/<uuid>-frames-*.png
:
sh
或使用默认调用System.cmd("/bin/sh", ["-c", "rm /path/to/dir/#{uuid}-frames-*.png"])
的{{1}}(注意单引号而不是双引号):
os:cmd/1
答案 1 :(得分:3)
调用System.cmd/2
的第二个参数中的路径“可执行文件将作为参数接收的二进制文件列表。”来自{ {3}}:
这意味着:
- 不会插入环境变量 - 不会发生通配符扩展(除非明确使用the documentation)
- 参数不需要为shell安全性进行转义或引用。
因此,要使用通配符,应该:
System.cmd("rm", Path.wildcard("/path/to/dir/" <> uuid <> "-frames-*.png"))
请注意,由于Path.wildcard/2
已经返回了一个列表,因此不应再包装它。
还有许多其他解决方法,但对于这种特殊情况,只需使用Path.wildcard/2
。