简体   繁体   中英

Resolving symlinks and “..” together in one path

Here is the problem. I have a symlink pointing to some other directory:

$ls -l /foo/bar
lrwxrwxrwx  /foo/bar  ->  /target/bar

in the foo directory there is a file x

$ls -l /foo
lrwxrwxrwx   me me  314   x

Now, I want to have an access to x by the following path /foo/bar/../x

$ls -l /foo/bar/../x : No such file or directory

This doesn't work in Bash, but is there any way to make it work from Java using the File api? The directory structure can be pretty much arbitrary so there might be cases like /foo/bar/1/2/3/4/5/../../../../../../x , etc.

In other words I am looking for the content of the magic() method checking the existence of a file (assuming the previously mentioned directory structure):

magic("/foo/x") ... true
magic("/foo/bar/../x") ... true
magic("/foo/bar/1//../../x") ... true
magic("/foo/bar/1/2/3/4/5/../../../../../../x") ... true
magic("/foo/bar//1/../2/../../x") ... true
magic("/foo/bar/1/2/../3/../../../x") ... true
magic("/foo/bar/1/2/./../3/../4//../../../x") ... true

magic("/foo/bar/x") ... false
magic("/foo/bar/1/../x") ... false
magic("/foo/bar/1/2/3/4/../../../../../../x") ... false
magic("/foo/bar//1/../2/../x") ... false

NOTE 1: getCanonicalPath() doesn't work for me, because it firstly resolves the symlinks and then all the ".." or "." in path. I need it to be done vice-versa.

NOTE 2: There might me other symlinks in the path and it should work in the same sense (dir 2 may be a symlink).

NOTE 3: The file x is located only in the /foo .

So far, it looks like I need a parser for context-free grammar, isn't there any easier solution to this problem?

If I understand you correctly, the Path.normalize() method should be doing exactly what you want?

It eliminates .. (among other things), and it's documentation says

This method does not access the file system; the path may not locate a file that exists. Eliminating ".." and a preceding name from a path may result in the path that locates a different file than the original path. This can arise when the preceding name is a symbolic link.

You don't need to resolve the other symlinks on the path, the OS will resolve them when you try to access the file in the end. If you want to resolve the symlinks anyway, call Path.toRealPath() afterwards ( not giving NOFOLLOW_LINKS as argument).

Path is a Java7 API. If you're stuck with Java6, I think the following would fit the bill, too: http://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/FilenameUtils.html#normalize%28java.lang.String%29

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM