Dans le manuel Bash ( man bash):
Substitution de commande
La substitution de commande permet à la sortie d'une commande de remplacer le
nom de la commande. Il existe deux formes:
$ (commande)
ou
`commande`
Bash effectue l'expansion en exécutant la commande dans un sous-shell
environnement et en remplaçant la substitution de commande par la norme
sortie de la commande, avec tous les retours à la ligne supprimés. Intégré
les sauts de ligne ne sont pas supprimés, mais ils peuvent être supprimés pendant le mot
scission. La substitution de commande $ (fichier cat) peut être remplacée par le
équivalent (mais plus rapide) $ (<fichier).
(Cela est vrai pour tous les Bourne comme des coquilles, par exemple sh, ksh, zsh, bashetc., et zshest également capable de capturer des données avec des caractères NUL intégrés de cette façon)
La commande
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
attribuera le nom du répertoire où se trouve le script (tout en changeant toutes les barres obliques inverses en barres obliques) à la variable basedir. Toutes les erreurs, avertissements ou autres messages de diagnostic qui sont transmis au flux d'erreurs standard seront toujours affichés sur le terminal ( $(...)capture uniquement la sortie standard de la commande).
Le shell commencera par exécuter la substitution de commande la plus interne:
echo "$0" | sed -e 's,\\,/,g'
La sortie de cela sera donnée sous forme de chaîne à dirname, et la sortie de celle-ci sera affectée à la variable basedir.
Les guillemets doubles sont là pour vous assurer qu'aucun fractionnement de mot ou remplacement de nom de fichier ne sera effectué, sinon vous pouvez constater que le script échoue ou produire une sortie étrange lorsque $0(le nom du script, y compris le chemin utilisé pour l'exécuter) contient un espace ou un caractère de remplacement de nom de fichier (tel que ?ou *).
C'est en général une bonne idée de toujours citer les extensions (extensions variables, substitutions de commandes et extensions arithmétiques). Voir cette question et ses réponses pour une excellente explication de pourquoi c'est une bonne idée.
Si le script a été exécuté en tant que
$ /usr/local/bin/script.sh
puis basedirva obtenir la valeur de /usr/local/bin.
Ou, sur Cygwin:
$ bash c:\\Users\\Me\\script.sh
puis basedirva obtenir la valeur de c:/Users/Me. Dans ce cas, les doubles barres obliques inverses sur la ligne de commande servent simplement à échapper les barres obliques inverses simples du shell. La valeur réelle de $0est c:\Users\Me\script.sh.
Une autre façon de faire la même chose sans utiliser dirname, echoet sedserait
basedir="${0//\\//}"
basedir="${basedir%/*}"
man bash