GNU/Linux >> Tutoriels Linux >  >> Linux

Les tests Bash sont-ils si pointilleux sur les espaces blancs ?

En tant que programmeur principalement Java, je trouve le bash ifthen construction assez déroutante, surtout en ce qui concerne les espaces blancs. Quelqu'un peut-il expliquer pourquoi le premier fonctionne, mais pas le deuxième ou le troisième ?

#works
if [ -n $1 ]; then echo "parameterized"; fi

#output: ./links: Zeile 1: [-n: Kommando nicht gefunden.
if [-n $1 ]; then echo "parameterized"; fi

#output: ./links: Zeile 1: [: Fehlende `]'
if [ -n $1]; then echo "parameterized"; fi

Réponse acceptée :

L'incohérence est en grande partie due à des raisons historiques.

L'utilisation de crochets comme commande conditionnelle est venue après l'utilisation de crochets dans les modèles de caractères génériques. Donc à l'époque [ -n foo ] est entré en scène, [foo] signifiait déjà "un fichier dont le nom est f ou o ”. Alors que peu d'utilisations de l'opérateur crochets dans la pratique auraient été en conflit avec des utilisations réalistes des crochets dans les caractères génériques, les auteurs ont choisi de ne pas risquer de casser les scripts existants en modifiant la syntaxe. Ce choix de conception a également facilité la mise en œuvre :initialement [ a été implémenté comme une commande externe, ce qui n'aurait pas pu être fait si l'espace après [ avait été facultatif. (Les systèmes modernes ont toujours [ en tant que commande externe, mais presque tous les shells modernes l'ont également intégré.)

Pour des raisons similaires, votre code "de travail" est en fait incorrect dans la plupart des cas. $1 ne signifie pas "la valeur du paramètre 1":cela signifie "prendre la valeur du paramètre 1, le diviser en mots séparés au niveau des espaces (ou quelle que soit la valeur de IFS est), et interpréter chaque mot comme un motif glob ». La façon d'écrire "la valeur du paramètre 1" nécessite des guillemets doubles :"$1" . Voir Quand les guillemets doubles sont-ils nécessaires ? pour les choses sérieuses. Vous n'avez pas besoin de comprendre cela; tout ce dont vous devez vous souvenir est :mettez toujours des guillemets doubles autour des substitutions de variables "$foo" et les substitutions de commandes "$(foo)" . Ainsi :

if [ -n "$1" ]; then …

Dans bash, ksh et zsh, mais pas dans sh simple, vous pouvez également utiliser des crochets doubles. Crochets simples [ … ] sont analysés comme une commande ordinaire (et en effet [ est une commande ordinaire, bien que généralement intégrée). Les crochets doubles sont une construction syntaxique distincte et vous pouvez omettre les guillemets doubles la plupart du temps.

if [[ -n $1 ]]; then …

Cependant, il existe une exception :[[ "$foo" = "$bar" ]] pour tester si les deux variables ont la même valeur nécessite des guillemets doubles autour de $bar , sinon $bar est interprété comme un modèle générique. Encore une fois, plutôt que de vous souvenir des détails, autant utiliser des guillemets doubles tout le temps.

Connexe :À partir de bash :arguments -lt et -gt ?
Linux
  1. Parenthèses dans la condition If :pourquoi ai-je des erreurs de syntaxe sans espace ?

  2. Quelles fonctionnalités sont dans Zsh et manquantes dans Bash, ou vice versa ?

  3. Que sont les séparateurs de mots Readline ?

  4. Des chaînes sont manquantes après la concaténation de deux chaînes variables ou plus dans Bash ?

  5. Quels sont les paramètres/variables spéciaux du shell (bash) ?

Bash Shebang

Qu'est-ce que ZFS ? Pourquoi les gens en sont-ils fous ?

Déclarations Bash If-Else - Tout ce que vous devez savoir sur

Commandes Bash utiles que vous ne connaissez peut-être pas

Comprendre comment les entrées sont envoyées aux canaux dans Bash

Noms d'hôte - De quoi s'agit-il ?