web-dev-qa-db-fra.com

Exécutez un script dans le même répertoire que le script actuel

J'ai deux scripts Bash dans le même dossier (enregistrés quelque part par l'utilisateur qui télécharge l'intégralité du référentiel):

  • script.sh est géré par l'utilisateur
  • helper.sh est requis et exécuté par script.sh

Les deux scripts doivent se trouver dans le même répertoire. J'ai besoin du premier script pour appeler le second, mais il y a deux problèmes:

  1. Je ne connais pas le répertoire de travail actuel, car je ne sais pas comment l'utilisateur exécute le premier script (pourrait être avec /usr/bin/script.sh, avec ./script.sh, ou ce pourrait être avec ../Downloads/repo/scr/script.sh)
  2. Le script script.sh sera remplacé par un autre répertoire avant d'appeler helper.sh.

Je peux certainement pirater ensemble Bash qui fait cela en stockant le répertoire actuel dans une variable, mais ce code semble inutilement compliqué pour ce que j'imagine être une tâche très courante et simple.

Existe-t-il un moyen standard pour de manière fiable appeler helper.sh de l'Intérieur script.sh? Et fonctionnera dans n'importe quel système d'exploitation pris en charge par Bash?

35
IQAndreas

Puisque $0 contient le chemin complet du script en cours d'exécution, vous pouvez utiliser dirname contre pour obtenir le chemin du script:

#!/bin/bash

script_name=$0
script_full_path=$(dirname "$0")

echo "script_name: $script_name"
echo "full path: $script_full_path"

donc si par exemple vous le stockez dans /tmp/a.sh alors vous verrez une sortie comme:

$ /tmp/a.sh
script_name: /tmp/a.sh
full path: /tmp

alors

  1. Je ne connais pas le répertoire de travail actuel, car je ne sais pas comment l'utilisateur exécute le premier script (pourrait être avec /usr/bin/script.sh, avec ./script.sh, ou ce pourrait être avec ../Downloads/repo/scr/script.sh)

En utilisant dirname "$0" vous permettra de garder une trace du chemin d'origine.

  1. Le script script.sh sera remplacé par un autre répertoire avant d'appeler helper.sh.

Encore une fois, puisque vous avez le chemin dans $0 vous pouvez cd y revenir.

44
fedorqui

$ 0 est considéré comme dangereux par de nombreux développeurs. J'ai trouvé une autre solution, elle est sûre pour une chaîne de scripts bash et source.

Si a.sh doit exécuter b.sh (qui se trouve dans le même dossier) en utilisant le processus bash enfant :

#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
bash ${__dir}/b.sh

Si a.sh doit exécuter b.sh (qui se trouve dans le même dossier) en utilisant le même processus bash:

#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source ${__dir}/b.sh
6
Eugen