J'écris un script bash. J'ai besoin que le répertoire de travail actuel soit toujours le répertoire dans lequel se trouve le script.
Le comportement par défaut est que le répertoire de travail actuel dans le script est celui du shell à partir duquel je l'exécute, mais je ne souhaite pas ce comportement.
myscript path/to/file
je m'attends à ce que le script évalue le chemin / vers / fichier par rapport à mon répertoire actuel, pas quel que soit le répertoire dans lequel le script se produit être situé dans. Aussi, que serait-il arrivé pour un script exécuté avecssh remotehost bash < ./myscript
comme le mentionne la FAQ BASH?cd "${BASH_SOURCE%/*}" || exit
Réponses:
la source
$0
. Dans votre script, vous pouvez vous attendre, par exemple,../../
à faire référence au répertoire deux niveaux au-dessus de l'emplacement du script, mais ce n'est pas nécessairement le cas si des liens symboliques sont en jeu../script
,.
est le bon répertoire, et le changer se.
terminera également dans le répertoire même où ilscript
se trouve, c'est-à-dire dans le répertoire de travail actuel.bash script.sh
, la valeur de$0
estscript.sh
. La seule façon dont lacd
commande "fonctionnera" pour vous est que vous ne vous souciez pas des commandes ayant échoué. Si vous deviez utiliserset -o errexit
(aka:)set -e
pour vous assurer que votre script ne dépasse pas les commandes ayant échoué, cela ne fonctionnerait PAS car ilcd script.sh
s'agit d'une erreur. La méthode fiable [spécifique à bash] estcd "$(dirname ${BASH_SOURCE[0]})"
Ce qui suit fonctionne également:
La syntaxe est décrite en détail dans cette réponse StackOverflow.
la source
bash script.sh
-$0
sera juste le nom du fichierEssayez les simples lignes simples suivantes:
Pour tous UNIX / OSX / Linux
Frapper
Remarque: Un double tiret (-) est utilisé dans les commandes pour signifier la fin des options de commande, afin que les fichiers contenant des tirets ou d'autres caractères spéciaux ne cassent pas la commande.
Remarque: Dans Bash, utilisez
${BASH_SOURCE[0]}
en faveur de$0
, sinon le chemin peut se casser lors de son sourcing (source
/.
).Pour Linux, Mac et autres * BSD:
Remarque:
realpath
devrait être installé par défaut dans la distribution Linux la plus populaire (comme Ubuntu), mais dans certains cas, il peut être manquant, vous devez donc l'installer.Remarque: Si vous utilisez Bash, utilisez
${BASH_SOURCE[0]}
en faveur de$0
, sinon le chemin peut se casser lors de son sourcing (source
/.
).Sinon, vous pouvez essayer quelque chose comme ça (il utilisera le premier outil existant):
Pour Linux spécifique:
Utilisation de GNU readlink sur * BSD / Mac:
Remarque: Vous devez avoir
coreutils
installé (par exemple 1. Installez Homebrew , 2.brew install coreutils
).En bash
Dans bash, vous pouvez utiliser des extensions de paramètres pour y parvenir, comme:
mais cela ne fonctionne pas si le script est exécuté à partir du même répertoire.
Vous pouvez également définir la fonction suivante dans bash:
Cette fonction prend 1 argument. Si l'argument a déjà un chemin absolu, imprimez-le tel quel, sinon imprimez l'
$PWD
argument variable + nom de fichier (sans./
préfixe).ou voici la version tirée du
.bashrc
fichier Debian :En relation:
Comment détecter le répertoire courant dans lequel j'exécute mon script shell?
Obtenez le répertoire source d'un script Bash à partir du script lui-même
Chemin absolu du script Bash avec OS X
Un moyen fiable pour un script Bash d'obtenir le chemin complet vers lui-même
Voir également:
Comment puis-je obtenir le comportement de readlink -f de GNU sur un Mac?
la source
cp
commande, @kenorb?--
) est utilisé dans les commandes pour signifier la fin des options de commande, afin que les fichiers contenant des tirets ou d'autres caractères spéciaux ne cassent pas la commande. Essayez par exemple de créer le fichier viatouch "-test"
ettouch -- -test
, puis supprimez le fichier viarm "-test"
etrm -- -test
, et voyez la différence.realpath
paquet Debian est obsolète, pas GNUrealpath
. Si vous pensez que ce n'est pas clair, vous pouvez suggérer une modification.C'est facile. Ça marche.
la source
cd "${BASH_SOURCE%/*}" || exit
La réponse acceptée fonctionne bien pour les scripts qui n'ont pas de lien symbolique ailleurs, comme dans
$PATH
.Cependant, si le script est exécuté via un lien symbolique,
Ce sera cd dans le
~/bin/
répertoire et non le~/project/
répertoire, ce qui cassera probablement votre script si le but de lacd
est d'inclure des dépendances par rapport à~/project/
La réponse sûre de lien symbolique est ci-dessous:
readlink -f
est requis pour résoudre le chemin absolu du fichier potentiellement lié.Les guillemets sont nécessaires pour prendre en charge les chemins de fichiers qui pourraient potentiellement contenir des espaces blancs (mauvaise pratique, mais il n'est pas sûr de supposer que ce ne sera pas le cas)
la source
Ce script semble fonctionner pour moi:
La ligne de commande pwd fait écho à l'emplacement du script en tant que répertoire de travail actuel, peu importe d'où je l'exécute.
la source
realpath
est peu susceptible d'être installé partout. Ce qui peut ne pas avoir d'importance, selon la situation du PO.realpath
mais il en areadlink
qui semble être similaire.Obtenez le vrai chemin vers votre script
(Ceci est la réponse à la même question ici: Obtenez le nom du répertoire où un script est exécuté )
la source
la source
PWD est une variable d'environnement.
la source
Si vous avez juste besoin d'imprimer le répertoire de travail actuel, vous pouvez suivre ceci.
Accordez l'autorisation d'exécution:
Exécutez ensuite le script d'ici
./test
là, vous pouvez voir le répertoire de travail actuel.la source
pwd
? Il me semble que beaucoup de touches ont été gaspillées.