使用System.cmd时,带有通配符的Elixir shell命令失败

时间:2018-04-21 03:42:35

标签: elixir phoenix-framework

我有一个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,因此不应该从字面上解释这个问题的范围。

2 个答案:

答案 0 :(得分:4)

json_decode($yourJsonVariable->pricing->in, true); 之类的通配符由shell扩展,而不是*。您的命令只会删除名为rm的文件。

您可以通过将命令传递给/path/to/dir/<uuid>-frames-*.png

等shell来扩展通配符
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