Parentesi in condizione if: perché ricevo errori di sintassi senza spazi bianchi?


17

Sto usando lo script di seguito per tornare indietro di due giorni quando lo script viene eseguito all'inizio di due giorni dell'anno e controllare anche il primo e il secondo giorno di ogni mese e tornare indietro di due giorni.

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

Ma il mio male sta ricevendo il seguente messaggio di errore

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found

1
Le risposte fornite sono corrette; hai bisogno di spazi bianchi dopo [. Inoltre, guarda elifnell'affermazione; ti aiuterà a ripulire le cose. Inoltre, i punti e virgola dopo le istruzioni if ​​non sono necessari, ma non sono anche errati, solo strani.
Shawn J. Goff,

@ ShawnJ.Goff Sono necessari se concatenate la riga successiva ( if [ ... ]; then), quindi non così insolito.
Riccioli d'oro

@goldilocks, sì, questo è il mio stile preferito. Il motivo per cui è insolito è perché non lo sta facendo.
Shawn J. Goff,

Risposte:


27

[non è né un metacarattere né un operatore di controllo (nemmeno una parola riservata; lo stesso per ]), quindi ha bisogno di spazi bianchi attorno ad esso. Altrimenti la shell "vede" il comando [01=01]invece del comando [con i parametri separati 01, =, 01, e ]. Ogni operatore e operando deve essere un argomento separato per il [comando, quindi è necessario anche uno spazio attorno agli operatori.

if [ "$month" = "01" ]

[$month="01"]è un modello jolly che corrisponde a uno dei caratteri in $montho "01. Se non corrisponde a nulla, viene lasciato solo.

Se è presente un punto e virgola dopo la parentesi quadra di chiusura, non è necessario uno spazio prima di esso, poiché il punto e virgola fa sempre parte di un token separato.

if [ "$month" = "01" ]; then

Lo stesso vale per la sintassi della doppia parentesi di bash (e di ksh e di zsh).

Più di una condizione

Esistono due modi per combinare le condizioni:

  1. entro [

  2. con [comandi separati combinati con &&o||

Raggruppare con parentesi è probabilmente più facile all'interno [.

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

Il primo dovrebbe essere evitato in quanto inaffidabile (provare ad esempio con month='!'). Problemi con strani contenuti variabili possono essere evitati usando prima la stringa sicura (se presente); o usando [[/ ]]invece di [/ ]:

if [ "01" = "$month" -a "01" = "$day" ]

Come possiamo abbinare le due condizioni in if, come valore del mese == valore del giorno se [$ mese = "01"] && [$ day = "01"]; mi aspetto 01 && 01 vero quindi stampa sotto le condizioni o passa alla frase else
Kumar1

@AshokSanganahalli Ho esteso la mia risposta.
Hauke ​​Laging,

1
[quando -a/ -onon sono utilizzati è sempre affidabile con shell conformi a POSIX. Non c'è alcun vantaggio nell'usare -a/-ooltre &&/||. Scoraggerei sicuramente il suo utilizzo. Si noti che [[non è POSIX.
Stéphane Chazelas,

4

Un altro modo di scriverlo:

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac

1
+1 per la casedichiarazione. Se ne hai più di uno elif, probabilmente dovresti usarlo case.
HalosGhost

-1

Quindi, questa è la tua risposta:

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

Quindi devi mettere "spazio" tra parentesi quadra e variabile / valore.


no, credo, perché come ho chiesto allo script di spostarsi indietro di due giorni quando lo script viene eseguito all'inizio di due giorni all'anno e controllare anche il primo e il secondo giorno di ogni mese e spostare due giorni indietro significa qui se [$ month = "01"] && [$ day = "01"] supponiamo di abbinare il mese "01" e il primo giorno "01" vero, passare a allora o passare ad altra condizione
Kumar1

1
@AshokSanganahalli: Non so come sia correlato, ma la tua condizione IF non funziona perché non hai "spazio vuoto" tra parentesi quadre e valore
Neven,

@AshokSanganahalli Di solito non è una buona idea per le persone del tuo livello di competenza contestare le correzioni da parte di persone con una comprensione ovviamente migliore senza almeno provare il suggerimento. Se le tue ipotesi fossero giuste, non dovresti chiedere qui, vero?
Hauke ​​Laging,

4
-1 per variabili non quotate e utilizzo ==invece di standard =.
Stéphane Chazelas,

2
La domanda non è taggata bash. L'operatore di confronto di uguaglianza nel comando aka standard[test è =. [se per i test, non svolge alcun compito, quindi non è necessario chiarire le ambiguità. Alcune [implementazioni supportano ==come estensione rispetto allo standard, ma non tutte. La Bourne shell, ash's, posh' s [s o /bin/[di alcuni sistemi, per esempio, non fanno. ==è stato aggiunto da ksh, suppongo per coerenza con lo stesso operatore nel suo nuovo (( ... ))costrutto (che ha sia = che ==, ma non è uno standard)
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.