How can I follow and fully report on a chain of symbolic links?

What are the best programming tools / techniques for performing complex nesting of symbolic links and complete capture and reporting of each symbolic link along the path, including in the middle of the path (see below for more information) .

Here is a concrete example. Consider the following shell command output

 ls -l /Library/Java/Home
 lrwxr-xr-x  1 root  admin  48 Feb 24 12:58 /Library/Java/Home -> /System/Library/Frameworks/JavaVM.framework/Home

The ls command lets you know that the / library / file of the Java / Home file is a symbolic link to another location. However, this does not let you know that the item it points to is also a symbolic link.

ls -l /System/Library/Frameworks/JavaVM.framework/Home
lrwxr-xr-x  1 root  wheel  24 Feb 24 12:58 /System/Library/Frameworks/JavaVM.framework/Home -> Versions/CurrentJDK/Home

This, in turn, does not let you know that part of the path of the specified file is a symbolic link.

ls -l /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK
lrwxr-xr-x  1 root  wheel  3 Feb 24 12:58 /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK -> 1.5

, ,

ls -l /System/Library/Frameworks/JavaVM.framework/Versions/1.5
lrwxr-xr-x  1 root  wheel  5 Feb 24 12:58 /System/Library/Frameworks/JavaVM.framework/Versions/1.5 -> 1.5.0

, "" .

- , - ( , )? , script ( , , !), , ", , ., ". , - .

/, , PHP- -. , , () , , /​​.

+3
5

Tcl [file type $filename], , . [file link $filename], , . , .

, - :

#!/usr/bin/tclsh

proc dereferenceLink {path {tree {}}} {
    if {[file type $path] == "link"} {
        set pointsTo [file link $path]
        if {[lsearch -exact $tree $path] >= 0} {
            lappend tree $path
            return "[join $tree ->] (circular reference)"
        } else {
            lappend tree $path
            return [dereferenceLink $pointsTo $tree]
        }
    } else {
        lappend tree $path
        return [join $tree "->"]
    }
}

puts [dereferenceLink [lindex $argv 0]]

, :

foo- > - >

, :

foo- > bar- > baz- > foo ( )

+1
+1

bash script , . " > " ​​ ls, . - ( , , , , ), .

#!/bin/bash 

function deref() {

    FILE="${1%/}"
    COUNT=0
    while [ -L "$FILE" ]; do
        TARGET=`ls -l "$FILE" | sed -e 's/^.*> //'`
        [ ${TARGET:0:1} == "/" ] || TARGET="`dirname $FILE`/$TARGET"

        # strip trailing slashes; -L cannot handle those
        FILE="${TARGET%/}"

        COUNT=$(( COUNT + 1 ))
        [ $COUNT -eq 10 ] && exit 1
    done
    echo $FILE

}

deref "$ 1"
+1
source

If you just need to know the final referent, php has a realpath function that can do this.

0
source

In PHP you can use is_linkand readlink.

Usage example:

function dereference_link($path) {
  $parts = array();
  foreach (explode(DIRECTORY_SEPARATOR, $path) as $part) {
    $parts[] = $part;
    $partial = implode(DIRECTORY_SEPARATOR, $parts);
    if (is_link($partial)) {
      $result = dereference_link(readlink($partial) . substr($path, strlen($partial)));
      array_unshift($result, $path);
      return $result;
    }
  }
  return array($path);
}
0
source

Source: https://habr.com/ru/post/1704925/


All Articles