Pergunta: existe um comando sh / bash / zsh / fish / ... simples para imprimir o caminho absoluto de qualquer arquivo que eu o alimente?
Caso de uso: Eu estou no diretório /a/b
e eu gostaria de imprimir o caminho completo para o arquivo c
na linha de comando para que eu possa facilmente colá-lo em outro programa: /a/b/c
. Simples, mas um pequeno programa para fazer isso provavelmente poderia me economizar 5 segundos ou mais quando se trata de lidar com caminhos longos, o que, no final, se soma. Então, me surpreende não poder encontrar um utilitário padrão para fazer isso - não existe realmente nenhum?
Aqui está uma implementação de exemplo, abspath.py:
#!/usr/bin/python
# Author: Diggory Hardy <[email protected]>
# Licence: public domain
# Purpose: print the absolute path of all input paths
import sys
import os.path
if len(sys.argv)>1:
for i in range(1,len(sys.argv)):
print os.path.abspath( sys.argv[i] )
sys.exit(0)
else:
print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
sys.exit(1)
Respostas:
Tente
realpath
.fonte
realpath
composto por: github.com/westonruter/misc-cli-tools/blob/master/realpathExperimente o
readlink
que resolverá os links simbólicos:fonte
-m
é a melhor opção para usar./usr/bin/readlink
em Mavericks. Ou você quis dizer que essas opções não são encontradas no OS X? Parece ser uma versão BSD atrofiada ...: preadlink
manpage:only the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an error
, então readlink não funcionará para esta finalidade no OSXfonte
a b
(dois espaços entre a e b, SO come um deles).function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }
me tornar umrealpath
comando (resposta atualmente aceita) no OS X. Obrigado!LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
Esqueça
readlink
erealpath
quais podem ou não estar instalados no seu sistema.Expandindo a resposta do dogbane acima aqui, ele é expresso como uma função:
você pode usá-lo assim:
Como e por que isso funciona?
A solução explora o fato de que o Bash embutido
pwd
comando imprime o caminho absoluto do diretório atual quando chamado sem argumentos.Por que gosto desta solução?
É portátil e não requer nenhum
readlink
ourealpath
que geralmente não existe em uma instalação padrão de uma determinada distribuição Linux / Unix.E se dir não existir?
Conforme indicado acima, a função falhará e será impressa no stderr se o caminho do diretório fornecido não existir. Pode não ser o que você deseja. Você pode expandir a função para lidar com essa situação:
Agora ele retornará uma string vazia se uma das diretivas pai não existir.
Como você lida com os caracteres '..' ou '.' na entrada?
Bem, dá um caminho absoluto nesse caso, mas não um caminho mínimo. Será parecido com:
Se você quiser resolver o '..', precisará fazer o script como:
fonte
realpath
vem do pacote coreutils, que também contém ferramentas comowho
,touch
oucat
. É um conjunto bastante padronizado de ferramentas GNU, para que você possa ter certeza de que ele está instalado em quase todas as máquinas baseadas em Linux. Dito isso, você está certo: há 2 problemas com ele: i) você provavelmente sentirá falta dele na instalação padrão em sistemas não-GNU unix (como o OpenBSD) ii) essas ferramentas foram introduzidas na versão 8.15 (portanto, é bastante nova a partir de 2012), portanto você sentirá falta de sistemas estáveis a longo prazo (como o RHEL 6).Isso é melhor que
readlink -e FILE
ourealpath
porque funciona mesmo que o arquivo não exista.fonte
-m
opção não está disponível no Mavericks.Esse caminho relativo para a função de shell do conversor de caminho absoluto
cd
epwd
)..
e.
Código:
Amostra:
Nota: Isso é baseado nas respostas de nolan6000 e bsingh , mas corrige a caixa do arquivo.
Também entendo que a pergunta original era sobre um utilitário de linha de comando existente. Mas, como essa parece ser a pergunta no stackoverflow, incluindo scripts shell que desejam ter dependências mínimas, coloquei essa solução de script aqui, para encontrá-la mais tarde :)
fonte
$ abspath 'a b c/file.txt'
Issocd
ocorre porque o argumento para não é citado. Para superar isso, em vez de citar o argumento inteiro paraecho
(existe uma razão para essas aspas?), Cite apenas os argumentos do caminho. Ou seja, substituaecho "$(cd ${1%/*}; pwd)/${1##*/}"
porecho $(cd "${1%/*}"; pwd)/${1##*/}
.echo "$(cd "$1"; pwd)"
por(cd "$1"; pwd)
. Não há necessidade de eco aqui.( ... )
ainda são necessários, o quecd
acontece em um subshell, pois não queremos alterar o diretório de trabalho de nenhum chamador deabspath
.O
find
comando pode ajudarLista todos os arquivos no diretório atual ou abaixo dele com nomes correspondentes ao padrão. Você pode simplificá-lo se obter apenas alguns resultados (por exemplo, diretório próximo ao final da árvore contendo poucos arquivos), apenas
Eu uso isso no Solaris 10, que não possui os outros utilitários mencionados.
fonte
PWD
, você pode simplesmente usar$PWD/$filename
.Se você não possui utilitários readlink ou realpath, pode usar a seguinte função, que funciona no bash e no zsh (não tem certeza sobre o resto).
Isso também funciona para arquivos inexistentes (assim como a função python
os.path.abspath
).Infelizmente
abspath ./../somefile
não se livra dos pontos.fonte
echo "$1"
porprintf "%s\n" "$1"
(o mesmo com o segundo eco).echo
pode interpretar barras invertidas dentro de seus argumentos.Aqui está uma função apenas do zsh que eu gosto por sua compacidade. Ele usa o modificador de expansão 'A' - consulte zshexpn (1).
fonte
Geralmente não há tal coisa como o
absolute path
para um arquivo (o que significa demonstração de que pode haver mais de um em geral, daí o uso do artigo definido o não é o caso). Anabsolute path
é qualquer caminho que começa na raiz "/" e designa um arquivo sem ambiguidade, independentemente do diretório de trabalho (veja, por exemplo, wikipedia ).A
relative path
é um caminho que deve ser interpretado a partir de outro diretório. Pode ser o diretório de trabalho se for umrelative path
sendo manipulado por um aplicativo (embora não necessariamente). Quando está em um link simbólico em um diretório, geralmente se destina a ser relativo a esse diretório (embora o usuário possa ter outros usos em mente).Portanto, um caminho absoluto é apenas um caminho relativo ao diretório raiz.
Um caminho (absoluto ou relativo) pode ou não conter links simbólicos. Caso contrário, também é um pouco impermeável a alterações na estrutura de ligação, mas isso não é necessariamente necessário ou mesmo desejável. Algumas pessoas chamam
canonical path
(oucanonical file name
ouresolved path
) umabsolute path
em que todos os links simbólicos foram resolvidos, ou seja, foram substituídos por um caminho para onde quer que eles estejam. Os comandosrealpath
e osreadlink
dois procuram um caminho canônico, mas sórealpath
têm uma opção para obter um caminho absoluto sem se preocupar em resolver links simbólicos (junto com várias outras opções para obter vários tipos de caminhos, absolutos ou relativos a algum diretório).Isso exige várias observações:
realpath
ereadlink
tem opções para explicar isso.canonical
. Portanto, o conceito depende do tempo (ou do ambiente).canonical path
para um arquivo, por dois motivos:ro
) em vários pontos de montagem.Portanto, mesmo com a definição muito mais restritiva de
canonical path
, pode haver vários caminhos canônicos para um arquivo. Isso também significa que o qualificadorcanonical
é um tanto inadequado, pois geralmente implica uma noção de singularidade.Isso expande uma breve discussão sobre o tópico em uma resposta a outra pergunta semelhante em Bash: recuperar o caminho absoluto dado
Minha conclusão é que
realpath
é melhor projetado e muito mais flexível do quereadlink
. O único usoreadlink
disso não cobertorealpath
é a chamada sem opção retornando o valor de um link simbólico.fonte
realpath
vsreadlink
ou mesmo sobre links simbólicos são excedentes ao que pedi.canonical
refere-se precisamente a essa singularidade em relação a um conjunto de transformações. Mas, por exemplo, / dev / cdrom é um caminho absoluto perfeitamente bom, embora seja realmente um link para / dev / sr0. Ambos apontam para o mesmo dispositivo. Minha resposta original apontou para um artigo relevante da web.A
dogbane
resposta com a descrição do que está por vir:Explicação:
"$1"
dirname "$1"
cd "$(dirname "$1")
entramos nesse diretório relativo e obtemos o caminho absoluto para ele executandopwd
comando shell$(basename "$1")
echo
elefonte
Para diretórios
dirname
é acionado../
e retorna./
.A função do nolan6000 pode ser modificada para corrigir isso:
fonte
.profile
e, portanto, disponível para uso interativo.$1
for um nome de arquivo simples:get_abs_filename foo
-> nothing (ou<current_dir>/foo/foo
sefoo
for um diretório).Esta não é uma resposta para a pergunta, mas para quem faz scripts:
ele lida com / .. ./ etc corretamente. Eu também parece trabalhar no OSX
fonte
Coloquei o seguinte script no meu sistema e chamo-o como um alias do bash para quando eu quiser pegar rapidamente o caminho completo para um arquivo no diretório atual:
Não sei por que, mas no OS X quando chamado por um script "$ PWD" se expande para o caminho absoluto. Quando o comando find é chamado na linha de comando, não é. Mas faz o que eu quero ... curtir.
fonte
$PWD
sempre tem o caminho absoluto do diretório de trabalho. Além disso,find
não tolerará barras, então você não está respondendo à pergunta conforme solicitado. Uma maneira mais rápida de fazer o que você está procurando é simplesmenteecho "$PWD/$1"
O mais simples se você deseja usar apenas os recursos internos é provavelmente:
Apenas duas palavras extras para digitar, e isso funcionará em todos os sistemas unix, bem como no OSX.
fonte
-maxdepth 1
antes-name
(supondo que o arquivo esteja no diretório atual). Sem isso, ele funcionará com arquivos em qualquer subdiretório do pwd, mas não com outros.find
, não encontrará um arquivo fora da árvore de diretórios abaixopwd
. Por exemplo, se você tentarfind . -name ../existingFile
, ele falhará.Isso compensa as deficiências de
realpath
, armazene-o em um script de shellfullpath
. Agora você pode ligar para:fonte
realpath "foo bar"
->/home/myname/foo bar
. Se você não pode se dar ao trabalho de citar argumentos da linha de comando, isso nãorealpath
é culpa.Uma alternativa para obter o caminho absoluto no Ruby :
realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}
Funciona sem argumentos (pasta atual) e caminho relativo e absoluto de arquivo ou pasta como um instrumento.
fonte
Responder com Homebrew
realpath
é a melhor resposta, mas se você não o tiver instalado, execute primeiro obrew install coreutils
que instalará o coreutils com muitas funções impressionantes. Escrever uma função personalizada e exportar é muito trabalho e risco de erro para algo como isto, aqui estão duas linhas:fonte
Ei pessoal, eu sei que é um tópico antigo, mas estou postando isso para referência a qualquer pessoa que tenha visitado isso como eu. Se entendi a pergunta corretamente, acho que o
locate $filename
comando. Ele exibe o caminho absoluto do arquivo fornecido, mas apenas se ele existir.fonte
locate
é um utilitário para procurar arquivos / caminhos por nome. Pode fazer o trabalho, mas também pode encontrar outras correspondências e pode não encontrar um arquivo existente sem chamarupdatedb
primeiro como root.