问题
Elixir 1.3.2
Erlang/OTP 19
Windows 7 (Standard User and Administrator)
I'm trying to hack together a small Elixir script to wrap around commiting files to git. The first thing I do, in order to insure I don't accidentally stage temporary files created by emacs is File.rm("*~"). However, this is what I get:
iex(2)> File.rm("*~")
{:error, :eio}
So I tried File.rm("*.*~")
. Same result. I get the same behavior when I run as either a Standard User (which is how I normally work on Windows) or as an administrator so it doesn't seem to be anything with permissions either.
So I captured the files into a list.
iex(15)> {:ok,files} = File.ls
{:ok,
[".git", ".gitattributes", ".gitignore", "add.factor", "async_ut",
"async_ut.cs", "cng_maint", "codecvg.cmd", "codecvg_rkt.cmd",
"codecvg_rkt.cmd~", "CreateBr.vbs", "DevSandbox", "distillery", "dk.cmd",
"example.scm", "example.sql", "factor", "fsele", "fsharp", "glp.vbs",
"lwwtww.org", "mrgmain.cmd", "MrgMain.vbs", "mrgtrunk.cmd", "mrgtrunk.cmd~",
(truncated to save space)
I can check for the strings in the list containing ~
and it comes back true. So I'm not imagining the tilde being there.
I created a temporary file called test.txt
in the directory. File.rm
removed that one just fine so it seems to be something about the ~
which is causing the issue. I also tried these:
iex(7)> File.rm("*\~")
{:error, :eio}
iex(8)> File.rm("*\7F") #7F is hex code of ~
{:error, :eio}
No luck as you can see.
Googling for anything about :eio
with Elixir and File.rm didn't turn up anything helpful. I can try installing 1.4.0 to see if that has an effect but I just wanted to see if I was missing something dumb and obvious here.
I've also got cygwin on the machine so I tried removing the files that way. rm *~
worked exactly as expected (under a standard user).
It seems as if this is somehow an Erlang specific issue but I'm aksing here first. Am I doing something obviously wrong?
回答1:
File.rm won't process wildcards automatically as far as I know, you need to use the Path.wildcard function:
File.rm(Path.wildcard("*~"))
or
Path.wildcard('*~') |> Enum.each(fn x -> File.rm(x) end)
for more than one file (which is probably the more general case.
回答2:
On the Unix command line, rm
will be called by the shell - and the shell is responsible for wildcard expansion, variable interpolation, etcetera before the actual command is called. So strictly speaking, Unix rm
does not support wildcards either - it's the shell that does; rm
just loops through its arguments and calls the unlink()
system call on each of them. The Erlang library mimics this behaviour.
(On Windows, the shell does not do wildcard expansion, at least not the classic shell - I don't know about PowerShell. Commands have to do this themselves, which is hugely annoying when writing command line utilities. At least, this was the state of the art when I dabbled in Windows ;-))
来源:https://stackoverflow.com/questions/41285984/why-cant-i-delete-files-with-a-tilde