dos系统运行java找不到符号,为什么从cmd.exe会话中看不到某些cygwin符号链接

Summary:

In the most recent (Sept. 2020) version of 64-bit cygwin, the symlinks in the /bin/ and /lib directories have puzzling features, and seem to differ from any of the various other documented symlinks. The questions are:

why are they hidden from CMD.EXE, but visible elsewhere, unlike

other symlink types

is it possible to create symlinks with identical features? if so, how?

TL;DR

See @matzeri's answer: the SYSTEM attribute is set on /bin/awk, making it invisible to CMD.EXE sessions.

The symlinks below /bin and /lib seem to be one of the two types of "default cygwin symlinks" described here:

The default symlinks created by Cygwin are either special reparse

points shared with WSL on Windows 10, or plain files containing a

magic cookie followed by the path to which the link points. The

reparse point is used on NTFS, the plain file on almost any other

filesystem.

see symbolic links

However, all of the symlinks below /bin have the SYSTEM attribute set, and most of the symlinks below /lib don't. I don't know how was I able to create a symlink with a magic cookie on NTFS.

Below is the long version of the question

There are multiple types of symlinks under cygwin. Other questions explain their history, describe their differences, and show how to create them, etc. For example:

Here's a discussion of some of the history and problems with symlinks on windows:

As described, there are shortcuts, junction points, and symlinks, all of which are visible from a CMD.EXE session, as demonstrated.

However, under my 64-bit cygwin installation, there is another type that I can't find any explanation for. A number of them appear below /bin, /lib, and perhaps other places. The main characteristic that distinguishes them from the other 3 is that they aren't visible from a CMD.EXE session.

Here's one example:

If I attempt to list 'awk' via CMD.EXE from the /bin directory, the file seems to not exist:

$ 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

Here's what it looks to to ls:

$ ls -l awk

lrwxrwxrwx 1 philwalk None 8 May 14 12:26 awk -> gawk.exe

But most symlinks, in my experience, ARE visible from a CMD.EXE session. Let's create a symlink for testing:

$ 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 ls-link [C:\cygwin64\bin\ls.exe]

1 File(s) 0 bytes

0 Dir(s) 295,290,556,416 bytes free

This shows that CMD.EXE can see this type of symlink.

It appears that all symlinks can be dereferenced like this:

$ cygpath -w `which awk`

C:\cygwin64\bin\gawk.exe

So can a windows-based program dereference them? Can it see them at all? Because they aren't visible to CMD.EXE, I would have guessed that they aren't visible to any other windows (i.e., non-cygwin) program.

Here's a scala script, deref.sc, that will test these questions:

#!/usr/bin/env scala

import java.nio.file._

for( posixPath

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("")

}

Here's the output from deref.sc as applied to /bin/awk and to ./ls-link.

(we have to pass the windows-visible version of /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]

So this shows that, although some windows programs (such as CMD.EXE) cannot see c:/cygwin64/bin/awk, others (such as jvm-based programs) can!

My original question was based on the mistaken assumption that windows programs are not able to see these new symlinks, and since that isn't correct, the residual question is:

What are these new symlinks, and how are they created? Are they really different, or is this perhaps a side-effect of permissions? Running CMD.EXE as administrator seems to make no difference.

I verified that c:/cygwin64/bin/awk is also visible from a WSL session, although that's not so surprising given that the jvm can see them.

UPDATE: it seems that, although /bin/awk is visible to our program, it isn't considered to be a symbolic link by java.nio.file.Files.isSymbolicLink(). Its contents consist of the string "!gawk.exe", so it seems to be an early cygwin implementation of symlinks, before windows provided native symlinks.

It's unremarkable except for being invisible from CMD.EXE.

解决方案

The reason why the links are not visible is due to their file Attribute

S = System are not visible in CMD by DOS/Windows design,

from CMD, sorry in German, we have:

$ cmd

Microsoft Windows [Version 10.0.19041.450]

(c) 2020 Microsoft Corporation. Alle Rechte vorbehalten.

D:\cygwin64\bin>attrib zipinfo

S D:\cygwin64\bin\zipinfo

D:\cygwin64\bin>dir zipinfo

Datenträger in Laufwerk D: ist DATA

Volumeseriennummer: D603-FB6E

Verzeichnis von D:\cygwin64\bin

Datei nicht gefunden

D:\cygwin64\bin>dir /A:S zipinfo

Datenträger in Laufwerk D: ist DATA

Volumeseriennummer: D603-FB6E

Verzeichnis von D:\cygwin64\bin

19.06.2018 22:17 16 zipinfo

1 Datei(en), 16 Bytes

0 Verzeichnis(se), 542.542.495.744 Bytes frei

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值