Descubra o destino do link simbólico via linha de comando

130

Digamos que eu configurei um link simbólico:

ln -s /root/Public/mytextfile.txt /root/Public/myothertextfile.txt

existe uma maneira de ver qual é o destino myothertextfile.txtusando a linha de comando?

Jared
fonte

Respostas:

171

Use a -fbandeira para imprimir a versão canônica. Por exemplo:

readlink -f /root/Public/myothertextfile.txt

De man readlink:

-f, --canonicalize
      canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
brian-brazil
fonte
8
Como sugerido em outra pergunta , você pode querer usar readlink -f.
Denilson Sá Maia
5
Para que isso funcione no Mac OS X brew install coreutils,. Isto instala versões GNU básicos de comandos pré-fixadas com a letra g, ou sejagreadlink -f somefile
Mike D
com opção -f, o comando retorna nada no meu caso ..
SOTN
Usar -f me deu as informações que eu queria, isto é, resolver vários links simbólicos e mostrar o destino final.
Isapir
nas Ubuntu 18.04.1 LTS (Bionic Beaver)páginas de manual do readlink, observe "Note realpath (1) é o comando preferido para usar na funcionalidade de canonização".
Sam Kamensky
23

readlink é o comando que você deseja. Você deve olhar a página do manual para o comando. Porque se você deseja seguir uma cadeia de links simbólicos para o arquivo real, precisará da opção -e ou -f:

$ ln -s foooooo zipzip   # fooooo doesn't actually exist
$ ln -s zipzip zapzap

$ # Follows it, but doesn't let you know the file doesn't actually exist
$ readlink -f zapzap
/home/kbrandt/scrap/foooooo

$ # Follows it, but file not there
$ readlink -e zapzap

$ # Follows it, but just to the next symlink
$ readlink zapzap
zipzip
Kyle Brandt
fonte
Nada de errado com a primeira resposta, mas esta é mais completa e útil.
Mike S
6

Isso também funcionará:

ls -l /root/Public/myothertextfile.txt

mas readlinkseria preferível para uso em um script, em vez de analisar ls.

Dennis Williamson
fonte
4

Se você quiser mostrar a fonte e o destino do link, tente stat -c%N files*. Por exemplo

$ stat -c%N /dev/fd/*
‘/dev/fd/0’ -> ‘/dev/pts/4’
‘/dev/fd/1’ -> ‘/dev/pts/4’

Não é bom para analisar (use readlinkpara isso), mas mostra o nome e o destino do link, sem a confusão dels -l

-cpode ser escrito --formate %Nsignifica "nome do arquivo citado com desreferencia se link simbólico".

Robert Siemer
fonte
2

A readlinké uma coisa boa, mas específico GNU e plataforma não cruz. Eu costumava escrever scripts de plataforma cruzada para /bin/sh, portanto, usava algo como:

 ls -l /root/Public/myothertextfile.txt | awk '{print $NF}'

ou:

 ls -l /root/Public/myothertextfile.txt | awk -F"-> " '{print $2}'

mas isso precisa ser testado em plataformas diferentes. Eu acho que eles funcionarão, mas não tenham 100% de certeza para lso formato de saída.

O resultado de lstambém pode ser analisado dentro bashsem depender de um comando externo como awk, sedou perl.

Esta bash_realpathfunção resolve o destino final de um link (link → link → link → final):

bash_realpath() {
  # print the resolved path
  # @params
  # 1: the path to resolve
  # @return
  # >&1: the resolved link path

  local path="${1}"
  while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
  do
    path="${BASH_REMATCH[1]}"
  done
  echo "${path}"
}
Роман Коптев
fonte
1

Se você não pode usar readlink, a análise do resultado ls -lpode ser feita assim.

O resultado normal seria:

ls -l /root/Public/myothertextfile.txt
lrwxrwxrwx 1 root root 30 Jan  1 12:00 /root/Public/myothertextfile.txt -> /root/Public/mytextfile.txt

Então, queremos substituir tudo antes de "->" e a seta incluída. Nós poderíamos usar sedpara isso:

ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
7ochem
fonte
1

A questão não é precisa o suficiente para dar uma resposta simples como a de brian-brazil:

readlink -f some_path

realmente desreferirá todos os links simbólicos envolvidos na construção do caminho para o destino final por trás some_path.

Mas um nível de links simbólicos em cascata é apenas um caso particular entre outros em um sistema, sendo o caso geral N níveis de links simbólicos em cascata. Veja o seguinte no meu sistema:

$ rwhich emacs
/usr/bin/emacs
 /etc/alternatives/emacs
  /usr/bin/emacs24-x

rwhiché minha própria implementação recursiva whichque imprime todos os links simbólicos em cascata intermediários (para stderr) até o destino final (para stdout).

Então, se eu quero saber o que é:

  • o destino do link simbólico / usr / bin / emacs **, a resposta óbvia para mim é a seguinte /etc/alternatives/emacs:

    readlink $(which emacs)
    readlink /usr/bin/emacs
    
  • o destino final por trás dos links simbólicos em cascata / usr / bin / emacs, a resposta será a seguinte /usr/bin/emacs24-x:

    readlink -f $(which emacs)
    readlink -f /usr/bin/emacs
    rwhich emacs 2>/dev/null
    
Nico
fonte
0

llou ls -ldeve listar os itens do diretório, incluindo seu link simbólico e seu destino

cd -P /root/Public/myothertextfile.txt (no seu caso) deve apontar para o caminho original

Mantz
fonte
0

Se você encontrar o destino de todos os links em uma pasta e sua subpasta, use o find . -type l -lscomando com o tipo de link da seguinte maneira:

[email protected]:~/test$ find . -type l -ls
8601855888        0 lrwxr-xr-x    1 me           staff                   6 Jan 24 19:53 ./link -> target

Se você quer o alvo de um único, então ls -ldeve funcionar:

[email protected]:~/test$ ls -l 
total 0
lrwxr-xr-x  1 me  staff  6 Jan 24 19:53 link -> target
-rw-r--r--  1 me  staff  0 Jan 24 19:53 target
Memin
fonte