I have an elixir program that needs to programmatically delete a variable amount of PNG files named as such.
/path/to/dir/<uuid>-frames-001.png
/path/to/dir/<uuid>-frames-002.png
/path/to/dir/<uuid>-frames-003.png
etc.
Naturally, I have come up with the following elixir code to delete these files.
System.cmd("rm", ["/path/to/dir/" <> uuid <> "-frames-*.png"])
I have seen the above code fail in multiple ways. First off, I have run it on server and seen the following stacktrace:
/bin/rm: cannot remove '/path/to/dir/<uuid>-frames-*.png': No such file or directory
I have also run this code on a console session and seen the exact same output.
If I run the following command in a bash session, it works fine!
rm /path/to/dir/<uuid>-frames-*.png
It returns a 0
error code and it deletes the expected files. It seems like elixir is interpreting the *
as a literal character, and not performing the expected wildcard delete. Any idea how to accomplish this? Thanks!
P.S.
Obviously, <uuid>
is an actual uuid and therefore should not be interpreted literally for the scope of this problem.
Wildcards like *
are expanded by the shell, not by rm
. Your command will only delete the file literally called /path/to/dir/<uuid>-frames-*.png
.
You can make the wildcard expand by passing the command to a shell like sh
:
System.cmd("/bin/sh", ["-c", "rm /path/to/dir/#{uuid}-frames-*.png"])
or use os:cmd/1
which by default invokes sh
(note the single quotes instead of double):
:os.cmd('rm /path/to/dir/#{uuid}-frames-*.png')
The path in the second argument in call to System.cmd/2
“a list of binaries which the executable will receive as its arguments as is.” From the documentation:
This means that:
— environment variables will not be interpolated
— wildcard expansion will not happen (unlessPath.wildcard/2
is used explicitly)
— arguments do not need to be escaped or quoted for shell safety.
So, to wildcard to work, one should:
System.cmd("rm", Path.wildcard("/path/to/dir/" <> uuid <> "-frames-*.png"))
Note, that since Path.wildcard/2
already returns a list, it should not be wrapped again.
There are many other workarounds, but for this particular case just use File.rm/1
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With