GNU/Linux >> Tutoriels Linux >  >> Linux

Citation dans $(substitution de commande) dans Bash ?

Dans mon environnement Bash, j'utilise des variables contenant des espaces, et j'utilise ces variables dans la substitution de commande.

Quelle est la bonne façon de citer mes variables ? Et comment dois-je faire si ceux-ci sont imbriqués ?

DIRNAME=$(dirname "$FILE")

ou est-ce que je cite en dehors de la substitution ?

DIRNAME="$(dirname $FILE)"

ou les deux ?

DIRNAME="$(dirname "$FILE")"

ou dois-je utiliser des back-ticks ?

DIRNAME=`dirname "$FILE"`

Quel est le bon moyen de le faire? Et comment puis-je vérifier facilement si les devis sont corrects ?

Réponse acceptée :

Dans l'ordre du pire au meilleur :

  • DIRNAME="$(dirname $FILE)" ne fera pas ce que vous voulez si $FILE contient des espaces (ou n'importe quel caractère $IFS contient actuellement) ou caractères globaux [?* .
  • DIRNAME=`dirname "$FILE"` est techniquement correct, mais les backticks ne sont pas recommandés pour l'expansion des commandes en raison de la complexité supplémentaire lors de leur imbrication et du traitement supplémentaire de la barre oblique inverse qui s'y produit.
  • DIRNAME=$(dirname "$FILE") est correct, mais uniquement parce qu'il s'agit d'une affectation à une variable scalaire (pas de tableau). Si vous utilisez la substitution de commande dans un autre contexte, tel que export DIRNAME=$(dirname "$FILE") ou du $(dirname -- "$FILE") , l'absence de guillemets causera des problèmes si le résultat de l'expansion contient des espaces blancs ou des caractères globaux.
  • DIRNAME="$(dirname "$FILE")" (sauf pour le -- manquant , voir ci-dessous) est la méthode recommandée. Vous pouvez remplacer DIRNAME= avec une commande et un espace sans rien changer d'autre, et dirname reçoit la chaîne correcte.

Pour s'améliorer encore :

  • DIRNAME="$(dirname -- "$FILE")" fonctionne si $FILE commence par un tiret.
  • DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit fonctionne même si $FILE Le nom du répertoire se termine par une nouvelle ligne, puisque $() coupe les nouvelles lignes à la fin de la sortie, à la fois celle ajoutée par dirname et celles qui peuvent faire partie des données réelles.

Vous pouvez imbriquer les extensions de commande autant que vous le souhaitez. Avec $() vous créez toujours un nouveau contexte de citation, vous pouvez donc faire des choses comme ceci :

foo "$(bar "$(baz "$(ban "bla")")")"

Vous ne faites pas je veux essayer ça avec des backticks.


Linux
  1. La commande "eval" dans Bash ?

  2. Syntaxe de déclaration de substitution de commande dans Bash - Laquelle de ces deux est la meilleure pratique ??

  3. Substitution de commande à l'aide de " ?

  4. démarrer apachectl à partir de bash

  5. commande d'exportation bash

Commande d'historique sous Linux (historique de bash)

Commande de sortie Bash et codes de sortie

Commande Bash printf

Script bash (II)

Script bash (III)

Utilisation de la commande Linux Dirname dans les scripts Bash