Pergunta

Quais são as melhores ferramentas / programação de técnicas para seguir um assentamento complicada de links simbólicos e completamente captura e relatórios sobre cada link ao longo do caminho, incluindo aqueles no meio de um caminho (veja abaixo para mais informações) .

Aqui está um exemplo específico. Considere o seguinte saída de um comando shell

 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

O comando ls permite que você saiba que o arquivo / Library / Java / Home é um link simbólico para outro local. No entanto, ele não permite que você sabe que a coisa está apontando é também um link simbólico

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

Este, por sua vez, não deixá-lo saber que parte do caminho do pontiagudo para arquivo é um link simbólico.

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

O que, apenas para completar este conto, é um outro link simbólico

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

Finalmente apontando para uma pasta "real".

Existem algumas ferramentas que podem visualizar toda a cadeia de links para você, de alguma forma (ou graficamente ou texto velho liso)? Eu tenho certeza que se poderia roteiro por si próprios (e se você quiser, por favor, fazê-lo e compartilhar!), Mas parece que o tipo de coisa que seria repleta de "oh, merda, caso extremo. Ah, merda, um outro caso extremo". Eu estou esperando que alguém já tinha ido para o incômodo.

Eu freelance / trabalho contrato, e todo mundo usa links simbólicos ligeiramente diferente para instalar suas aplicações PHP em um servidor web. Metade do meu trabalho é geralmente un-nidificação este (inevitavelmente) hierarquia não documentada por isso sabemos onde colocar os nossos novos códigos / módulos.

Foi útil?

Solução

Tcl tem um comando [tipo de arquivo $ filename] que irá retornar "link" se é um link. Tem outro comando [arquivo de link $ filename] que irá retornar o que o link aponta. Com esses dois comandos é possível tomar um link e siga os links até chegar a um arquivo real.

Talvez algo parecido com isso em cima da minha cabeça:

#!/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]]

Você vai obter uma saída que se parece com:

foo-> bar-> baz

Se há um link circular será parecido com:

foo-> bar-> baz-> foo (circular referência)

Outras dicas

Este script python faria isso, se você adicionou um único print dentro do loop:

http://mail.python.org/pipermail /python-ideas/2007-December/001254.html

Aqui está um script que eu joguei junto um back tempo para fazer exatamente isso. Ele encontra a ">" no ls saída que indica um link simbólico para andar as ligações. Eu não posso garantir para o comportamento perfeito em casos extremos (é codificado para desistir depois de seguir links de dez, a fim de loops de evitar, por exemplo), mas funcionou bem para mim.

#!/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"

Em PHP, você pode usar is_link e readlink .

Exemplo de utilização:

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);
}

Se você só precisa saber o referente último, php tem a href="http://php.net/realpath" rel="nofollow noreferrer"> realpath função que pode fazer isso.

scroll top