Respostas:
Use a -f
bandeira 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
brew install coreutils
,. Isto instala versões GNU básicos de comandos pré-fixadas com a letra g
, ou sejagreadlink -f somefile
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".
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
Isso também funcionará:
ls -l /root/Public/myothertextfile.txt
mas readlink
seria preferível para uso em um script, em vez de analisar ls
.
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 readlink
para isso), mas mostra o nome e o destino do link, sem a confusão dels -l
-c
pode ser escrito --format
e %N
significa "nome do arquivo citado com desreferencia se link simbólico".
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 ls
o formato de saída.
O resultado de ls
também pode ser analisado dentro bash
sem depender de um comando externo como awk
, sed
ou perl
.
Esta bash_realpath
funçã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}"
}
Se você não pode usar readlink
, a análise do resultado ls -l
pode 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 sed
para isso:
ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
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 which
que 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
Se você encontrar o destino de todos os links em uma pasta e sua subpasta, use o find . -type l -ls
comando com o tipo de link da seguinte maneira:
me@local.localdomain:~/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 -l
deve funcionar:
me@local.localdomain:~/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
readlink -f
.