Como saber se estou realmente em um local de link simbólico na linha de comando?

33

Suponha que eu tenha uma pasta:

cd /home/cpm135/public_html

e faça um link simbólico

ln -s /var/lib/class .

Mais tarde, estou nesse diretório:

cd /home/cpm135/public_html/class

O pwdvai me dizer que estou em/home/cpm135/public_html/class

Existe alguma maneira de saber que eu estou "realmente" dentro /var/lib/class? obrigado

Oliver Williams
fonte
1
Algumas conchas na verdade não permitem que você esteja dentro de um link simbólico. Por exemplo, o fishshell resolve automaticamente o link simbólico quando você cdentra nele.
trysis

Respostas:

56

Dependendo de como seu pwdcomando estiver configurado, pode ser o padrão para mostrar o diretório de trabalho lógico (produzido por pwd -L) que mostraria o local do link simbólico ou o diretório de trabalho físico (produzido por pwd -P) que ignora o link simbólico e mostra o diretório "real".

Para obter informações completas, você pode fazer

file "$(pwd -L)"

Dentro de um link simbólico, isso retornará

/path/of/symlink: symbolic link to /path/of/real/directory
Zanna
fonte
1
sim, a -Pbandeira era o que eu precisava. Obrigado
Oliver Williams
6
Para também responder à pergunta no título, use test "$(pwd -L)" = "$(pwd -P)" && echo No symlinks(ou substitua && echo No symlinkspor || echo Symlinks).
um CVn
1
Isso responde à pergunta perfeitamente, sem a necessidade de eco. Se a pergunta fosse 'Como exibir uma mensagem se estou em um diretório com link simbólico? ", O eco seria necessário.
Arronical
file "$(pwd)"funciona apenas se o link simbólico for o último componente do diretório. Ele não detecta o link simbólico do OP quando está em CD /home/cpm135/public_html/class/foo/bar. Eu não estou ciente de qualquer coisa que imprime informações para todos os links simbólicos em um caminho, mas você também pode usar realpath ., que acho que é equivalente apwd -P
Peter Cordes
17

Observe que, pwdna verdade, é um shell embutido. Dependendo do seu shell e sua configuração, os resultados podem mudar. Para uma solução mais portátil, você deve usar /bin/pwd. Snippet da página de manual:

NAME
       pwd - print name of current/working directory

SYNOPSIS
       pwd [OPTION]...

DESCRIPTION
       Print the full filename of the current working directory.

       -L, --logical
              use PWD from environment, even if it contains symlinks

       -P, --physical
              avoid all symlinks

       --help display this help and exit

       --version
              output version information and exit

       If no option is specified, -P is assumed.

       NOTE:  your  shell  may  have  its  own  version of pwd, which usually supersedes the version described here.  Please refer to your shell's documentation for
       details about the options it supports.

Em geral, você pode resolver o caminho canônico completo de qualquer arquivo / diretório usando readlink -f. readlink -f .funciona de forma semelhante a pwd -P.

Gowtham
fonte
2
Embora eu aprendi a maneira dura que readlink -fnão está disponível em todos os Unices (por exemplo, não está disponível no OS-X)
abligh
3

Você realmente está dentro /home/cpm135/public_html/class- essa é a única resposta correta para a pergunta "qual é o meu diretório de trabalho atual".

Quando você se refere a /var/lib/class... não é exatamente onde você está, mas mais sobre o caminho que você usou para chegar lá .

Quando você executa /bin/pwd, ele descobre seu diretório de trabalho atual observando o. e .. diretórios (os listados na parte superior de ls -la), calculando qual diretório em .. combina com. e depois trabalhando para trás até ... e. consulte o mesmo diretório. Uma vez feito tudo isso, ele sabe qual é o seu diretório de trabalho atual.

Quando você executa o pwdshell interno, ele não segue este procedimento (embora possa fazer parte dele, se necessário) - em vez disso, lembra o caminho que você seguiu para chegar até aqui. Portanto, toda vez que você executa um cdcomando, seu shell se lembra disso como parte do caminho para chegar onde está agora e pwdimprime o que foi calculado com base em todos os cdcomandos que você executou - o que pode ou não ser o seu real diretório de trabalho.

As coisas podem ficar realmente estranhas quando você faz um ln -s . fooe continua cdno foo - /bin/pwddirá que você ainda está no mesmo diretório, mas o shell interno pwddirá que você está /foo/foo/foo/foo/foo/foo- mesmo que esse diretório não exista. (Dito isto - você provavelmente pode cd .)

Outra fonte de confusão é se os diretórios forem renomeados. /bin/pwdentão, a mudança será feita imediatamente, mas o built-in pwdnão será feito até que você faça algo que indique que o nome do diretório antigo não importa.

dougmc
fonte
1
Você não está respondendo à pergunta, está descartando.
Dmitry Grigoryev
4
Embora isso não responda diretamente à pergunta , acho que é uma publicação útil para entender a diferença entre o shell pwdinterno /bin/pwde explicar como a versão autônoma fornece informações mais úteis (que podem responder à pergunta original).
Anthony G - justice para Monica
1
Todas essas diferenças se resumem às opções -Pe -Lmencionadas por outras respostas. Em resumo, algumas implementações são padronizadas para uma, outras para a outra. No sistema Centos que tenho em mãos, o built-in do bash está padronizado para lógico e /bin/pwdfísico, mas ambos aceitam as duas opções de linha de comando e concordam com o resultado quando são fornecidos.
IMSOP
1
A pergunta é baseada em uma premissa incorreta - 'existe alguma maneira de saber que eu estou "realmente" em / var / lib / class? " Dito isto ... ao explicar o que isso realmente significa, ele o ajuda a entender o que ele realmente está procurando. As opções pwd -P e -L já haviam sido mencionadas ...
dougmc
1
Você tem seu argumento ao contrário. ls ..irá mostrar o conteúdo de /var/lib, não /home/cpm135/public_html. cd ..é especial: o shell faz um rastreamento especial de "como você chegou lá" e, na verdade, não faz uma chdir("..")chamada de sistema. No que diz respeito ao kernel, o diretório de trabalho atual do seu shell ( /proc/self/cwd) é apenas um par mountpoint: inode. É como um descritor de arquivo aberto no diretório, e é por isso que renomear o diretório não quebra seu shell. ( cd .para atualizar a $PWDvariável do shell ). Você está fazendo um ponto útil, então eu upvote isso quando fixo
Peter Cordes
1

Essencialmente, você está perguntando se há para mostrar o caminho real do diretório de trabalho atual. Bem, existe com python e os.getcwd()função

O que você vê abaixo é um pequeno teste no diretório "VirtualBox VMs", localizado no meu diretório pessoal. Na realidade, é um link simbólico para um diretório diferente localizado em um disco rígido diferente, montado em /mnt/HDD.

bash-4.3$ file "$(pwd)"
/home/xieerqi/VirtualBox VMs: symbolic link to /mnt/HDD/VirtualBox VMs/
bash-4.3$ python -c 'import os; print os.getcwd()'
/mnt/HDD/VirtualBox VMs

Como você pode ver, o python's os.getcwd()resolve o caminho real do diretório, não o caminho do link simbólico.

Sergiy Kolodyazhnyy
fonte