问题描述
摘要:
在最新版本(2020年9月)的64位cygwin中,/bin/
和/lib
目录中的符号链接具有令人费解的功能,并且似乎与所记录的其他各个版本有所不同符号链接。问题是:
-
为什么它们对CMD.EXE隐藏,但在其他地方可见,不像 其他符号链接类型
-
是否可以创建具有相同功能的符号链接?如果可以,怎么办?
TL; DR
请参阅@matzeri的答案:SYSTEM属性设置为/bin/awk
,使其对CMD.EXE会话不可见。
/bin
和/lib
下的符号链接似乎是此处所述的两种“默认cygwin符号链接”之一:
Cygwin创建的默认符号链接是特殊解析的 Windows 10上与WSL共享的点,或包含 魔术cookie,然后是链接指向的路径。的 重解析点用于NTFS,几乎所有其他文件都使用纯文件 文件系统。 参见symbolic links
但是,/bin
下的所有符号链接均已设置SYSTEM属性,而/lib
下的大多数符号链接均未设置。我不知道如何在NTFS上使用魔术cookie创建符号链接。
下面是问题的长版
cygwin下有多种类型的符号链接。其他问题可以解释它们的历史,描述它们的差异以及显示如何创建它们,等等。例如:
check the difference of symlink type in cygwin
这里是有关Windows符号链接的一些历史和问题的讨论:
Symlinks on the mounted Windows directories are not compatible with native
如前所述,有一些快捷方式,连接点和符号链接,所有这些都可以从CMD.EXE会话中看到,如所示。
但是,在我的64位cygwin安装下,还有另一种类型,我找不到任何解释。其中有一些出现在/bin
,/lib
下方,也许还有其他地方。它们与其他3个区别的主要特征是它们在CMD.EXE会话中不可见。
这里是一个例子: 如果我尝试通过/ bin目录中的CMD.EXE列出“ awk”,则该文件似乎不存在:
$ cd /bin
$ cmd.exe /c dir awk
Volume in drive C is opt
Volume Serial Number is D0C8-EA58
Directory of C:\cygwin64\bin
File Not Found
ls
的外观如下:
$ ls -l awk
lrwxrwxrwx 1 philwalk None 8 May 14 12:26 awk -> gawk.exe
但是,根据我的经验,大多数符号链接在CMD.EXE会话中可见。让我们创建一个用于测试的符号链接:
$ CYGWIN=winsymlinks:nativestrict # make sure we don't create an old-style symlink
$ ln -s `which ls.exe` ls-link
$ cmd.exe /c dir ls-link
Volume in drive C is opt
Volume Serial Number is D0C8-EA58
Directory of C:\opt\ue
2020-09-03 13:12 <SYMLINK> ls-link [C:\cygwin64\bin\ls.exe]
1 File(s) 0 bytes
0 Dir(s) 295,290,556,416 bytes free
这表明CMD.EXE可以看到这种符号链接。
似乎所有符号链接都可以像这样被取消引用:
$ cygpath -w `which awk`
C:\cygwin64\bin\gawk.exe
那么基于Windows的程序可以取消引用它们吗?它可以看到他们吗?因为它们对CMD.EXE不可见,所以我猜想它们对任何其他Windows(即非Cygwin)程序都不可见。
这是一个scala脚本deref.sc
,它将测试以下问题:
#!/usr/bin/env scala
import java.nio.file._
for( posixPath <- args ){
val cyg = cygpath(posixPath)
val windows = Paths.get(posixPath)
val exists = Files.exists(windows)
printf("file path [%s]\n",posixPath )
printf("cygpath [%s]\n",cyg)
printf("windows [%s]\n",windows)
if( exists ){
printf("exists [%s] # visible to jvm-based programs\n",exists)
} else {
printf("exists [%s] # NOT visible to jvm-based programs\n",exists)
}
val realpath = if( exists ){
if( Files.isSymbolicLink(windows) ){
Files.readSymbolicLink(windows)
} else {
windows.toRealPath()
}
}
printf("real windows [%s]\n",realpath)
printf("\n")
}
def cygpath(posixPath:String) = {
import scala.sys.process._
Seq("cygpath.exe","-m",posixPath).lazyLines_!.mkString("")
}
这是deref.sc的输出,应用于/ bin / awk和./ls-link。 (我们必须传递Windows可见的/ bin / awk版本)
$ deref.sc ls-link
cygpath [ls-link]
windows [.\ls-link]
exists [true] # visible to jvm-based programs
real windows [C:\cygwin64\bin\ls.exe]
$ cd /bin
$ deref.sc awk
file path [awk]
cygpath [C:/cygwin64/bin/gawk.exe]
windows [awk]
exists [true] # visible to jvm-based programs
real windows [C:\cygwin64\bin\awk]
因此,这表明,尽管某些Windows程序(例如CMD.EXE)看不到c:/ cygwin64 / bin / awk,但其他Windows程序(例如基于jvm的程序)可以看到!
我最初的问题是基于一个错误的假设,即Windows程序无法看到这些新的符号链接,并且由于这是不正确的,因此剩余的问题是:
这些新的符号链接是什么,如何创建?它们真的不同吗,或者这可能是权限的副作用?以管理员身份运行CMD.EXE似乎没有任何作用。
我验证了c:/cygwin64/bin/awk
在WSL会话中也是可见的,尽管考虑到jvm可以看到它们,这并不奇怪。
更新:似乎/bin/awk
虽然对我们的程序可见,但java.nio.file.Files.isSymbolicLink()
并不将其视为符号链接。它的内容由字符串"!<symlink>gawk.exe"
组成,因此在Windows提供本机符号链接之前,它似乎是符号链接的早期cygwin实现。
除了从CMD.EXE中不可见之外,其他都没有。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)