通过FileUtils.symlink 'X', 'Y'
在ubuntu上创建符号链接在windows上工作时发生以下错误:
C:/ruby/lib/ruby/2.0.0/fileutils.rb:349:in `symlink': symlink() function is unimplemented on this machine (NotImplementedError)
from C:/ruby/lib/ruby/2.0.0/fileutils.rb:349:in `block in ln_s'
from C:/ruby/lib/ruby/2.0.0/fileutils.rb:1567:in `fu_each_src_dest0'
from C:/ruby/lib/ruby/2.0.0/fileutils.rb:347:in `ln_s'
from C:/test/test.rb:7:in `<class:Test>'
from C:/test/test.rb:1:in `<main>'
作为解决方法,可以通过
mklink
在windows上创建符号链接,但我也希望通过ruby在windows上创建符号链接。 最佳答案
发布这个丑陋的黑客有点尴尬,但如果你只是想让它工作,你可以重新定义方法,并外壳出到mklink。mklink有点复杂,因为它不是一个独立的程序。mklink是一个cmd.exe shell命令。
下面是文件类。对于fileutils,您可以替换类名并重新定义所需的方法,如下所示in the docs
require 'open3'
class << File
alias_method :old_symlink, :symlink
alias_method :old_symlink?, :symlink?
def symlink(old_name, new_name)
#if on windows, call mklink, else self.symlink
if RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/
#windows mklink syntax is reverse of unix ln -s
#windows mklink is built into cmd.exe
#vulnerable to command injection, but okay because this is a hack to make a cli tool work.
stdin, stdout, stderr, wait_thr = Open3.popen3('cmd.exe', "/c mklink #{new_name} #{old_name}")
wait_thr.value.exitstatus
else
self.old_symlink(old_name, new_name)
end
end
def symlink?(file_name)
#if on windows, call mklink, else self.symlink
if RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/
#vulnerable to command injection because calling with cmd.exe with /c?
stdin, stdout, stderr, wait_thr = Open3.popen3("cmd.exe /c dir #{file_name} | find \"SYMLINK\"")
wait_thr.value.exitstatus
else
self.old_symlink?(file_name)
end
end
end