comando realpath no encontrado

24

Tengo Debian Squeeze AMD64. Mi caparazón actual es bash. Si escribo lo siguiente en mi terminal, funciona:

$ 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

Mi archivo test.sh se ve así:

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

Si intento ejecutar lo siguiente, aparece un error

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

¿Cómo puedo usar el comando realpath dentro de un archivo bash?

Información 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
fuente

Respuestas:

9

¿Realpath es un comando real o un script? Verificaría de dónde viene.

$ type -a realpath

No estoy familiarizado con esta herramienta, por lo que es probable que no sea parte de su distribución normal, tal vez esté instalada en una ubicación no estándar que no está presente en Bash's $PATH pero está dentro de su entorno de inicio de sesión $PATH.

En cualquier caso, el typecomando anterior le mostrará de dónde viene el comando, momento en el que puede modificar el método que está llamando en su script de la siguiente manera:

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

O enmendar el guión $PATH para que también incluya esta ubicación no estándar.

Funciones en el caparazón

Gran parte de su entorno no recibe llamadas cuando invoca un script de shell. Si piensa en esto, tiene mucho sentido, ya que generalmente no desea que los scripts tengan todo el equipaje adicional que pueda tener el entorno de un usuario.

Puede determinar qué archivo fuente proporciona esta función y obtenerla, o simplemente indicarle a Bash que incorpore su entorno de inicio de sesión.

#!/bin/bash -l
echo $(realpath "$1")
slm
fuente
Es una función, ver edición
Francis
@Francis: sí, las funciones no están incluidas cuando invocas tu script. Tendrá que buscarlos si quiere que vengan. Averigüe qué archivo proporciona la función y búsquelo. Si solo quieres todo tu env. a continuación, modificar su llamada a la fiesta, #!/bin/bash -l.
slm
¿Cómo puedo encontrar de dónde viene esta función?
Francis
1
@mikeserv - gracias, cuando escribí esto todavía estaba usando Fedora 14 que no incluía realpath. Mi sistema Fedora 19 ahora incluye esta herramienta. Observe también que el OP estaba usando un núcleo Debian w / 2.6, por lo que su sistema también habría faltado realpathdada su antigüedad.
slm
1
@mikeserv: sí, me sorprendió, esta es una Q antigua, pero la información sobre esto commandtodavía me fue útil. Es una forma más portátil de hacer lo que estaba mostrando en los shells POSIX.
slm
27

Hay al menos dos programas llamados realpath:

  • Un antiguo programa de la época en que los coreutils de GNU no incluían readlink -f. Ahora está en desuso a favor readlink -f, por lo que muchas distribuciones han dejado de llevarlo.
  • El realpathprograma introducido en GNU coreutils 8.15. Esto es demasiado viejo para estar en Debian squeeze o incluso sibilante; al momento de escribir, Debian inestable tampoco lo envía . Este programa está muy cerca de readlink -f.

Por alguna razón, tiene una función de shell que emula parcialmente el comportamiento de realpath. Esta emulación es parcial: si la llamas en un enlace simbólico, no sigue el enlace simbólico.

Como se trata de una función de shell, presumiblemente cargada desde o a través de .bashrc, solo está disponible para el código que se ejecuta en su shell interactivo. Si desea que esté disponible para otros programas, suponiendo que esté ejecutando Linux, cree un script que emule realpath:

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

(Esto no emula realpathlas opciones de línea de comandos poco utilizadas).

Gilles 'SO- deja de ser malvado'
fuente
2
No puedo encontrar ninguna evidencia en el repositorio de coreutils git de que el realpathprograma se considera obsoleto por coreutils, o que no está construido de forma predeterminada. Entonces Debian debe eliminarlo.
Kaz
@Kaz Oh, bueno, solo para complicar las cosas, coreutils recientemente (8.15) introdujo un realpathbinario, que es cercano pero no exactamente idéntico readlink -f. Debian estable lleva 8.13. Debian inestable eligió mantener el programa heredado .
Gilles 'SO- deja de ser malvado'
No era que hace poco - era Ene 2012. savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv
1
@mikeserv Demasiado reciente para la distribución en la pregunta (compresión de Debian). Incluso demasiado reciente para la actual versión estable de Debian.
Gilles 'SO- deja de ser malvado'
Eso da un poco de miedo. ¿Cuántos años tienen openssl?
mikeserv
8

Funciona solo en shell, porque el archivo de secuencia de comandos tiene un alcance diferente y no tiene acceso a sus funciones locales y alias definidos en sus archivos rc . Y el realpathcomando en realidad no existe en su sistema.

Por lo tanto, instale realpathdesde el paquete, defina su propia función (como parte del script, verifique algunos ejemplos ) o busque el archivo rc en su script donde está definido (por ejemplo . ~/.bashrc).


Estos son los pasos para instalar realpathsi no está presente:

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

Ubuntu y Debian

En Debian o Ubuntu parece que realpathdebería instalarse por defecto. Revisé el reciente Debian 8 (Jessie) y parece que se coreutilsinstaló por defecto.

Probado con nuevas imágenes de VM:

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

Luego en VM:

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

En lugar de realpath, también puede usar readlink -f file(o greadlink) proporcionado por el coreutilspaquete también.

kenorb
fuente
5
$ sudo apt-get install realpath
usuario175315
fuente