Lors de l'écriture d'un script bash, comment obtenir le chemin absolu de l'emplacement du fichier actuel?

16

Supposons que j'ai un fichier bash appelé myBash.bash. Il réside dans:

/myDirect/myFolder/myBash.bash

Maintenant, je veux utiliser la chaîne /myDirect/myFolder(l'emplacement de myBash.bash) à l'intérieur du script. Existe-t-il une commande que je peux utiliser pour trouver cet emplacement?

Edit: L'idée est que je veux mettre en place un dossier zip avec du code qui peut être démarré par un script bash à l'intérieur de ce fichier zip. Je connais les chemins de fichiers relatifs du code à l'intérieur de ce fichier zip, mais pas les chemins absolus, et j'en ai besoin. Une façon serait de coder en dur dans le chemin, ou d'exiger que le chemin du fichier soit donné sous forme de variable. Cependant, je trouverais plus facile s'il était possible pour le fichier bash de déterminer où il se trouve tout seul, puis de créer les chemins d'accès appropriés à l'autre fichier à partir de sa connaissance de la structure du fichier zip.

dimpol
la source
3
Cela pourrait être mieux adapté au stackoverflow. Vérifiez ces questions: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/… .
Sethos II
1
utiliser comment.? veuillez clarifier
Sergiy Kolodyazhnyy
1
@SethosII cette question est totalement sur le sujet ici
Zanna
1
J'ai ajouté plus de contexte à la question. Je pensais qu'il pourrait y avoir une commande facile / évidente pour obtenir le chemin d'accès au fichier en cours d'exécution, mais il semble que la réponse soit au moins non évidente.
dimpol
3
@Zanna Je ne dis pas que c'est hors sujet, je pense que c'est juste plus approprié et comme le montrent les liens déjà demandés et y ont répondu plusieurs fois.
Sethos II

Réponses:

24

Vous pouvez obtenir le chemin complet comme:

realpath "$0"

Et comme l'a souligné Serg, vous pouvez utiliser dirnamepour supprimer le nom de fichier comme ceci

dirname "$(realpath $0)"

ou encore mieux pour éviter les citations et les séparations de mots difficiles avec des noms de fichiers difficiles:

temp=$( realpath "$0"  ) && dirname "$temp"

Beaucoup mieux que mon idée précédente qui était de l'analyser (je savais qu'il y aurait une meilleure façon!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Remarques

  • realpath retourne le chemin réel d'un fichier
  • $0 est ce fichier (le script)
  • s|old|new|remplacer oldparnew
  • \(.*\)/enregistrer tous les caractères avant /pour plus tard
  • \1 la partie sauvegardée
Zanna
la source
2
+1 pour l'utilisation de $0et la sedmagie. Mais cette sedmagie n'est vraiment pas nécessaire lorsque des outils comme ceux-ci dirnameexistent
Sergiy Kolodyazhnyy
2
vous avez déjà la réponse, utilisez realpath: realpath "$( dirname $0 )"personnellement, j'utiliserais readlinkmais c'est moi:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy
@Serg: Ce ne serait pas dirname "$(realpath "$0")"mieux? Habituellement, on veut connaître le répertoire parent du fichier référencé au lieu du répertoire parent du lien symbolique faisant référence audit fichier.
David Foerster
4
@Serg "$(dirname "$(realpath "$0")")"est le moyen le plus simple. Les citations à l'intérieur $()fonctionnent normalement.
DépriméDaniel
@DepressedDaniel A fait un peu de recherche en ligne, vous avez raison: $()être un sous-shell permettra d'avoir des devis à l'extérieur. Je ne dirais pas que c'est aussi simple, sauf si l'on se rend compte que ce $()sont tous des sous
coquilles
5

si le script se trouve sur votre chemin, vous pouvez utiliser quelque chose comme

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDIT: après avoir lu les commentaires de Serg, cela pourrait être une solution générique qui fonctionne que le script soit sur votre chemin ou non.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
Antonello Piemonte
la source
whichconvient mieux lorsque le script réside dans l'un des répertoires faisant partie de la PATHvariable. Utilisez-le à $0partir d'un script, comme le montre Zanna. Mais votre réponse est correcte puisque vous utilisez dirnameau lieu de jouer avec sed, donc +1 pour cela
Sergiy Kolodyazhnyy
5

La réponse acceptée semble parfaite. Voici une autre façon de procéder:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdaffiche le vrai chemin du répertoire, par opposition à la pwdcommande intégrée.

serv-inc
la source
0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

Il est pris comme référence de kenorb et andro
Pas de dirname, readlink, realpath, BASH_SOURCE
Tous sont intégrés

HemanthJabalpuri
la source