commande realpath introuvable

24

J'ai debian squeeze amd64. Mon shell actuel est bash. Si j'écris ce qui suit dans mon terminal, cela fonctionne:

$ 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

Mon fichier test.sh ressemble à ceci:

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

Si j'essaie d'exécuter ce qui suit, j'obtiens une erreur

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

Comment puis-je utiliser la commande realpath dans un fichier bash?

Information additionnelle

$ 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
la source

Réponses:

9

Realpath est-il une commande réelle ou un script? Je vérifierais d'où ça vient.

$ type -a realpath

Je ne connais pas cet outil, et donc il ne fait probablement pas partie de votre distribution normale, peut-être qu'il est installé dans un emplacement non standard qui n'est pas présent sur Bash $PATHmais se trouve dans votre environnement de connexion $PATH.

Dans tous les cas, la typecommande ci-dessus vous montrera d'où vient la commande, à quel point vous pouvez modifier la méthode que vous l'appelez dans votre script comme suit:

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

Ou modifiez vos scripts $PATHafin qu'ils incluent également cet emplacement non standard.

Fonctions dans le shell

Une grande partie de votre environnement n'est pas appelée lorsque vous appelez un script shell. Si vous y réfléchissez, cela a beaucoup de sens, car vous ne voulez généralement pas que les scripts aient tous les bagages supplémentaires que l'environnement d'un utilisateur peut avoir.

Vous pouvez soit déterminer quel fichier source fournit cette fonction et soit le source, soit simplement demander à Bash d'intégrer votre environnement de connexion.

#!/bin/bash -l
echo $(realpath "$1")
slm
la source
C'est une fonction, voir modifier
Francis
@Francis - oui, les fonctions ne sont pas incluses lorsque vous appelez votre script. Vous devrez les trouver si vous voulez qu'ils viennent. Découvrez quel fichier fournit la fonction et sourcez-la. Si vous voulez juste tout votre env. puis modifier votre appel à bash, #!/bin/bash -l.
slm
Comment savoir d'où vient cette fonction?
Francis
1
@mikeserv - merci, quand j'ai écrit ceci, j'utilisais toujours Fedora 14 qui ne comprenait pas realpath. Mon système Fedora 19 inclut désormais cet outil. Notez également que l'OP utilisait un noyau Debian avec 2.6, de sorte que son système aurait également été manquant realpathcompte tenu de son âge.
slm
1
@mikeserv - ouais j'ai été surpris, c'est un vieux Q maintenant, mais les informations sur commandm'ont toujours été utiles. C'est une façon plus portable de faire ce que je montrais sur des shells POSIX.
slm
27

Il existe au moins deux programmes appelés realpath:

  • Un ancien programme de dos quand GNU coreutils ne comprenait pas readlink -f. Il est désormais obsolète en faveur de readlink -f, de nombreuses distributions ont donc cessé de le porter.
  • Le realpathprogramme introduit dans GNU coreutils 8.15. C'est trop vieux pour être dans Debian Squeeze ou même sifflant; au moment de la rédaction, Debian unstable ne l’envoie pas non plus . Ce programme est très proche readlink -f.

Pour une raison quelconque, vous avez une fonction shell qui émule en partie le comportement de realpath. Cette émulation est partielle: si vous l'appelez sur un lien symbolique, elle ne suit pas le lien symbolique.

Comme il s'agit d'une fonction shell, probablement chargée depuis ou via .bashrc, elle n'est disponible que pour le code s'exécutant dans votre shell interactif. Si vous souhaitez qu'il soit disponible pour d'autres programmes, en supposant que vous exécutez Linux, créez un script qui émule realpath:

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

(Cela n'émule pas les realpathoptions de ligne de commande rarement utilisées.)

Gilles 'SO- arrête d'être méchant'
la source
2
Je ne trouve aucune preuve dans le référentiel git coreutils que le realpathprogramme est considéré comme obsolète par coreutils, ou qu'il n'est pas construit par défaut. Debian doit donc le supprimer.
Kaz
@Kaz Oh, eh bien, pour compliquer les choses, coreutils a récemment (8.15) introduit un realpathbinaire, qui est proche mais pas exactement identique à readlink -f. Debian stable porte 8.13. Debian unstable a choisi de conserver le programme hérité .
Gilles 'SO- arrête d'être méchant'
Ce n'était pas si récent - c'était en janvier 2012. savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv
1
@mikeserv Beaucoup trop récent pour la distribution dans la question (Debian squeeze). Encore trop récent pour l'écurie Debian actuelle.
Gilles 'SO- arrête d'être méchant'
C'est un peu effrayant. Quel âge a leur openssl?
mikeserv du
8

Il fonctionne uniquement en shell, car le fichier de script a une portée différente et n'a pas accès à vos fonctions et alias locaux définis dans vos fichiers rc . Et la realpathcommande n'existe pas réellement dans votre système.

Donc, installez à realpathpartir du package, définissez votre propre fonction (dans le cadre du script, consultez quelques exemples ) ou sourcez le fichier rc dans votre script là où il est défini (par exemple . ~/.bashrc).


Voici les étapes à installer realpaths'il n'est pas présent:

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

Ubuntu et Debian

Sur Debian ou Ubuntu, il semble que le realpathdevrait être installé par défaut. J'ai vérifié la récente Debian 8 (Jessie) et elle semble s'être coreutilsinstallée par défaut.

Testé en utilisant de nouvelles images VM:

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

Puis en VM:

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

Au lieu de realpath, vous pouvez également utiliser readlink -f file(ou greadlink) fourni par coreutilspackage.

kenorb
la source
5
$ sudo apt-get install realpath
user175315
la source