329 votes

Erreur "opérateur unaire attendu" dans la condition "if" de Bash

Ce script obtient une erreur :

elif [ $operation = "man" ]; then
    if [ $aug1 = "add" ]; then         # <- Line 75
    echo "Man Page for: add"
    echo ""
    echo "Syntax: add [number 1] [number 2]"
    echo ""
    echo "Description:"
    echo "Add two different numbers together."
    echo ""
    echo "Info:"
    echo "Added in v1.0"
    echo ""
elif [ -z $aug1 ]; then
    echo "Please specify a command to read the man page."
else
    echo "There is no manual page for that command."
fi

Je reçois cette erreur :

calc_1.2: line 75: [: =: unary operator expected

4 votes

Je pense que votre if à la ligne 75 a besoin d'un fi .

9 votes

En cas de doute, citez les vars.

13 votes

@koola, vars de citation 'toujours'.

716voto

rici Points 45980

Si vous savez que vous allez toujours utiliser Bash, il est beaucoup plus facile de toujours utiliser la commande conditionnelle composée entre crochets doubles. [[ ... ]] au lieu de la version entre crochets simples compatible POSIX. [ ... ] . A l'intérieur d'un [[ ... ]] le découpage des mots et l'expansion des chemins ne sont pas appliqués aux mots, vous pouvez donc compter sur

if [[ $aug1 == "and" ]];

pour comparer la valeur de $aug1 avec la chaîne and .

Si vous utilisez [ ... ] vous devez toujours vous rappeler de mettre les variables entre guillemets comme ceci :

if [ "$aug1" = "and" ];

Si vous ne citez pas l'expansion de la variable et que la variable est indéfinie ou vide, elle disparaît de la scène du crime, laissant seulement

if [ = "and" ];

ce qui n'est pas une syntaxe valide. (Il échouerait également avec un message d'erreur différent si $aug1 y compris les espaces blancs ou les métacaractères du shell).

Le moderne [[ possède de nombreuses autres fonctionnalités intéressantes, notamment la correspondance d'expressions régulières.

12 votes

"moderne" ? Est-ce que [[ ] siempre été dans le Bash ? Il est dans le shell Korn depuis plus de vingt ans, et est antérieur à bash. (Je sais ce que vous voulez dire cependant)

0 votes

@cdarke A propos, à la page 113 de la 3ème édition de Learning the Bash Shell, "[[ .. ]] n'est pas disponible dans les versions de bash antérieures à 2.05". Dans le pdf en ligne de doc.lagout.org, c'est à la page 326 !

2 votes

@spen.smith : selon le FAQ Bash , [[ a été ajouté à Bash dans la version 2.02 (1998), sur la base de la norme ksh fonction disponible depuis les années 1980. En 2012, lorsque cdarke a écrit ce commentaire, il était déjà raisonnable de dire qu'elle était "dans le shell Korn depuis plus de 20 ans." Mon utilisation du mot "moderne" en 2012 était certainement discutable ; aujourd'hui, elle serait ridicule. Mais bon, il y a encore des programmeurs qui insistent pour qu'une norme C publiée il y a 21 ans soit trop moderne pour être utilisée :-).

47voto

Juha Vehnia Points 311

Il m'a fallu du temps pour trouver cela, mais notez que si vous avez une erreur d'espacement, vous obtiendrez également la même erreur :

[: =: unary operator expected

Correct :

if [ "$APP_ENV" = "staging" ]

vs

if ["$APP_ENV" = "staging" ]

Comme toujours, le réglage -x La variable de débogage aide à les trouver :

set -x

8voto

yilee Points 1

Essayez d'attribuer une valeur à $aug1 avant de l'utiliser dans if[] le message d'erreur disparaîtra ensuite.

1voto

einarc Points 335

Assurez-vous que lorsque vous comparez une variable comme $operation en utilisant la comparaison de chaînes de caractères, vous ne laissez pas la possibilité que $operation renvoie une chaîne vide si vous utilisez l'approche POSIX (parenthèse simple).

Les deux [ $operation == "man"] et [ "" == "man" ] retournent la même erreur : [ : == : opérateur unaire attendu

De plus, vous ne devriez pas utiliser l'opérateur = à moins que vous ne soyez entre crochets, comme indiqué ci-dessus.

Référence : https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

0voto

Stuart Points 61

Cette erreur peut également se produire en lisant numérique l'entrée qui pourrait être vierge (pour accepter un option par défaut ).

La solution consiste à structurer le if avec plusieurs conditions et testez d'abord une variable vide.

Par exemple :

# sanitise input
var=$(echo $ans | tr -cd "[:digit:]")

if [ -z "$var" ] || [ "$var" -lt 1 ]; then
   do_something
fi

Je devais résoudre ce problème unary operator expected question dans remove_old_pkgs() de l'aide script abk para Modules de signalisation d'arc .

Voir aussi 6.4 Expressions conditionnelles de Bash

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X