comando realpath não encontrado

24

Eu tenho o debian squeeze amd64. Meu shell atual é bash. Se eu escrever o seguinte no meu terminal, ele funcionará:

$ uname -a
Linux core 2.6.32-5-amd64 #1 SMP Fri May 10 08:43:19 UTC 2013 x86_64 GNU/Linux
$ echo $SHELL
/bin/bash                                                                                                                                                                                     
$ echo $(realpath test.sh)                                                                                                                                                     
/home/ffortier/test.sh

Meu arquivo test.sh fica assim:

#!/bin/bash
echo $(realpath "$1")

Se eu tentar executar o seguinte, recebo um erro

$ ./test.sh test.sh 
./test.sh: line 2: realpath: command not found

Como posso usar o comando realpath em um arquivo bash?

informação adicional

$ type -a realpath
realpath is a function                                                                                                                                                                        
realpath ()                                                                                                                                                                                   
{                                                                                                                                                                                             
    f=$@;                                                                                                                                                                                     
    if [ -d "$f" ]; then                                                                                                                                                                      
        base="";                                                                                                                                                                              
        dir="$f";                                                                                                                                                                             
    else                                                                                                                                                                                      
        base="/$(basename "$f")";                                                                                                                                                             
        dir=$(dirname "$f");                                                                                                                                                                  
    fi;                                                                                                                                                                                       
    dir=$(cd "$dir" && /bin/pwd);                                                                                                                                                             
    echo "$dir$base"                                                                                                                                                                          
}           
Francis
fonte

Respostas:

9

Realpath é um comando ou script real? Eu verificaria para ver de onde vem.

$ type -a realpath

Eu não estou familiarizado com esta ferramenta e, portanto, provavelmente não faz parte da sua distribuição normal, talvez esteja instalada em um local não padrão que não esteja presente no Bash, $PATHmas que esteja dentro do seu ambiente de login $PATH.

De qualquer forma, o typecomando acima mostrará de onde o comando está vindo; nesse momento, você poderá alterar o método que está chamando no seu script da seguinte maneira:

echo $(/path/to/realpath test.sh)

Ou altere o script $PATHpara que ele também inclua esse local não padrão.

Funções no shell

Grande parte do seu ambiente não é chamado quando você invoca um script de shell. Se você pensar sobre isso, faz muito sentido, pois geralmente você não deseja que os scripts tenham toda a bagagem adicional que o ambiente de um usuário possa ter.

Você pode determinar qual arquivo de origem está fornecendo essa função e a fonte, ou simplesmente instruir o Bash para incorporar seu ambiente de login.

#!/bin/bash -l
echo $(realpath "$1")
slm
fonte
É uma função, consulte editar
Francis
@Francis - sim, as funções não são incluídas quando você invoca seu script. Você precisará obtê-los se quiser que eles venham. Descubra qual arquivo está fornecendo a função e a origem. Se você quer apenas todo o seu ambiente. em seguida, altere sua chamada para o bash #!/bin/bash -l,.
Slm
Como posso descobrir de onde vem essa função?
Francis
11
@ mikeserv - obrigado, quando escrevi isso, eu ainda estava usando o Fedora 14, que não incluía realpath. Meu sistema Fedora 19 agora inclui esta ferramenta. Observe também que o OP estava usando um kernel Debian w / 2.6, então seu sistema também estaria ausente realpathdevido à sua idade.
Slm
11
@ MikeServ - Sim, fiquei surpreso, este é um Q antigo agora, mas as informações sobre commandainda eram úteis para mim. É uma maneira mais portátil de fazer o que eu estava mostrando nos shells POSIX.
Slm
27

Existem pelo menos dois programas chamados realpath:

  • Um programa antigo de volta quando o GNU coreutils não incluía readlink -f. Agora está obsoleto em favor de readlink -f, muitas distribuições deixaram de carregá-lo.
  • O realpathprograma introduzido no GNU coreutils 8.15. É muito velho para estar no modo Debian ou até chiado; no momento em que escrevo, o Debian instável também não o envia . Este programa está muito próximo readlink -f.

Por alguma razão, você tem uma função shell que emula parcialmente o comportamento de realpath. Essa emulação é parcial: se você a chamar em um link simbólico, ela não seguirá o link simbólico.

Como essa é uma função do shell, presumivelmente carregada de ou via .bashrc, ela está disponível apenas para o código em execução no seu shell interativo. Se você deseja que ele esteja disponível para outros programas, supondo que você esteja executando o Linux, crie um script que emule realpath:

#!/bin/sh
readlink -f -- "$@"

(Isso não emula realpathas opções de linha de comando raramente usadas.)

Gilles 'SO- parar de ser mau'
fonte
2
Não consigo encontrar nenhuma evidência no repositório coreitils git de que o realpathprograma é considerado reprovado pelo coreutils ou de que não foi criado por padrão. Então o Debian deve estar removendo-o.
Kaz
@Kaz Oh, bem, só para complicar, o coreutils recentemente (8.15) introduziu um realpathbinário próximo, mas não exatamente idêntico readlink -f. O Debian stable carrega 8.13. O Debian instável escolheu manter o programa legado .
Gilles 'SO- stop be evil'
Não era que recentemente - era Jan 2012. savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv
11
@mikeserv Muito recente para a distribuição na questão (squeeze do Debian). Ainda muito recente para o atual Debian estável.
Gilles 'SO- stop be evil'
Isso é meio assustador. Qual a idade deles openssl?
precisa saber é o seguinte
8

Funciona apenas no shell, porque o arquivo de script tem escopo diferente e não tem acesso às funções e aliases locais definidos nos arquivos rc . E o realpathcomando realmente não existe no seu sistema.

Portanto, instale a realpathpartir do pacote, defina sua própria função (como parte do script, verifique alguns exemplos ) ou origine o arquivo rc no seu script onde está definido (por exemplo . ~/.bashrc).


Aqui estão as etapas para instalar realpathse não estiver presente:

  • Ubuntu: sudo apt-get install coreutils
  • OS X: brew install coreutils

Ubuntu e Debian

No Debian ou Ubuntu, parece que realpathdeve ser instalado por padrão. Eu verifiquei no recente Debian 8 (Jessie) e parece ter sido coreutilsinstalado por padrão.

Testado usando imagens novas da VM:

$ vagrant init debian/jessie64 && vagrant up --provider virtualbox && vagrant ssh
$ vagrant init ubuntu/vivid64 && vagrant up --provider virtualbox && vagrant ssh

Então na VM:

$ type -a realpath
realpath is /usr/bin/realpath

Em vez de realpath, você também pode usar readlink -f file(ou greadlink) fornecido pelo coreutilspacote.

kenorb
fonte
5
$ sudo apt-get install realpath
user175315
fonte