Quelle est cette variable de formulaire = $ (…)

9

Qu'est-ce que cela signifie:

basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

Je suis particulièrement intéressé par cette partie:

varible=$(...)

Je sais que les parenthèses sont utilisées pour exécuter un sous-processus, mais que faire si elles sont utilisées avec $?

Maxim Koretskyi
la source
3
Si vous utilisez bash: man bash
consultez la

Réponses:

16

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%/*}"
Kusalananda
la source
merci, donc il commence essentiellement à analyser à partir de la parenthèse la plus interne, correct? et pourquoi les citations sont-elles utilisées?
Maxim Koretskyi
@Maximus Correct. J'ai mis à jour ma réponse avec plus d'informations.
Kusalananda
Peut-être que vous devriez dire "vaut pour tous les obus de type Bourne". Un peu plus clair de cette façon
Sergiy Kolodyazhnyy
@Serg, notez que le shell Bourne (comme celui /bin/shde Solaris 10 ou antérieur) n'était pas compatible $(...).
Stéphane Chazelas
@ StéphaneChazelas Je vais intégrer cela.
Kusalananda
6

Cela signifie exécuter ce qui est à l'intérieur des parenthèses dans un sous - shell et renvoyer cela en tant que valeur , dans votre cas en l'assignant à varible.

marc
la source