Confronto di numeri interi: espressione aritmetica o espressione condizionale

In Bash, è possibile confrontare due numeri interi utilizzando lespressione condizionale

arg1 OP arg2

OP è uno di -eq, -ne, -lt, -le, -gt o -ge. Questi operatori binari aritmetici restituiscono true se arg1 è uguale a, non uguale a, minore di, minore o uguale a, maggiore o maggiore o uguale a arg2 , rispettivamente. Arg1 e arg2 possono essere numeri interi positivi o negativi.

o espressione aritmetica:

<= >= < > confronto

== != uguaglianza e disuguaglianza

Perché abbiamo due modi diversi per confrontare due numeri interi? Quando usarlo?

Ad esempio, [[ 3 -lt 2 ]] utilizza lespressione condizionale e (( 3 < 2 )) utilizza lespressione aritmetica. Entrambi restituiscono 0 quando il confronto è vero

Quando si confrontano due numeri interi, questi due metodi possono sempre essere utilizzati in modo intercambiabile? Se sì, perché Bash ha due metodi anziché uno?

Commenti

  • = != < <= > >= confronta stringhe . 1 -eq 01 ma 1 != 01 e 8 -lt 42 ma 8 > 42
  • Sono sovraccariche di espressioni aritmetiche.
  • ‘ dovrai cercare nei log delle modifiche di bash per scoprire quando ogni funzione è stata aggiunto. Sospetto che le espressioni aritmetiche siano state aggiunte molto più tardi del comando test.
  • Non sto chiedendo di confrontare le stringhe. @muru.

Risposta

Sì, abbiamo due modi diversi per confrontare due numeri interi.

Sembra che questi fatti non siano ampiamente accettati in questo forum:

  1. Allinterno dellidioma [ ] gli operatori per il confronto aritmetico sono -eq, -ne, -lt, -le, -gt e -ge.

    Poiché si trovano anche allinterno di un comando di prova e di un [[ ]].

    Sì allinterno di questi idiomi, =, < e così via sono operatori stringa.

  2. Allinterno dellidioma (( )) gli operatori per il confronto aritmetico sono == , !=, <, <=, > e >=.

    No, questo non è un “aritmo etic espansione “(che inizia con un $) come $(( )). È definito come un “Comando composto” in man bash.

    Sì, segue le stesse regole (internamente) dell “espansione aritmetica” ma non ha output, solo un valore di uscita. Potrebbe essere usato in questo modo:

if (( 2 > 1 )); then ... 

Perché abbiamo due modi diversi per confrontare due numeri interi?

Immagino che questultimo (( )) sia stato sviluppato come un modo più semplice per eseguire test aritmetici. È quasi uguale a $(( )) ma non ha output.

Perché due? È lo stesso del motivo per cui abbiamo due printf (esterno e incorporato) o quattro test (esterno test, incorporato test, [ e [[). Questo è il modo in cui crescono i gusci, migliorando unarea in un anno, migliorandone unaltra lanno successivo.

Quando usarla?

Questa “è una domanda molto difficile perché non dovrebbe esserci alcuna differenza effettiva. Ovviamente ci sono alcune differenze nel modo in cui un [ ] funziona e un (( )) funzionano internamente, ma: quale è meglio confrontare due numeri interi? Uno qualsiasi !.

Quando si confrontano due numeri interi, questi due metodi possono sempre essere usati in modo intercambiabile?

Per due numeri sono costretto a dire di sì.
Ma per le variabili, le espansioni , operazioni matematiche potrebbero esserci differenze chiave che dovrebbero favorire luna o laltra. Non posso dire che assolutamente entrambi siano uguali. Per prima cosa, (( )) potrebbe eseguire diverse operazioni matematiche in sequenza:

if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi 

Se sì, perché Bash ha due metodi invece di uno?

Se entrambi sono utili, perché no ?.

Commenti

  • = è unassegnazione e == è un confronto nelle espansioni aritmetiche. La domanda lo cita correttamente. Ma la risposta è sbagliata.
  • Inoltre ( non è una parola riservata in bash, quindi non è necessario inserire spazi intorno a ((, poiché opposto a [ o [[

Risposta

Storicamente, il comando test esisteva per primo (almeno fino a Unix Settima Edizione nel 1979). Utilizzava gli operatori = e != per confrontare le stringhe e -eq, -ne, -lt e così via per confrontare i numeri. Ad esempio, test 0 = 00 è falso, ma test 0 -eq 00 è vero. Non so perché è stata scelta questa sintassi, ma potrebbe essere stato per evitare di utilizzare < e >, che la shell avrebbe analizzato come operatori di reindirizzamento. Il comando test ha ricevuto unaltra sintassi pochi anni dopo: [ … ] è equivalente a test ….

La [[ … ]] sintassi condizionale, allinterno della quale < e > può essere utilizzato come operatori senza virgolette, è stato aggiunto in seguito, in ksh. Ha mantenuto la compatibilità con [ … ], quindi ha utilizzato gli stessi operatori, ma ha aggiunto < e > per confrontare le stringhe (ad esempio, [[ 9 > 10 ]] ma [[ 9 -lt 10 ]]). Per ulteriori informazioni, vedere utilizzo di parentesi singole o doppie – bash

Anche le espressioni aritmetiche sono arrivate dopo test comando,

nella shell Korn , a un certo punto negli anni 80. Hanno seguito la sintassi del linguaggio C, che era molto popolare nei circoli Unix. Pertanto hanno utilizzato gli operatori di C “s:==per luguaglianza,<=per minore o uguale, ecc.

Unix Seventh Edition non “aveva espressioni aritmetiche, ma aveva il comando expr , che implementava anche un Sintassi simile a C per operazioni su interi, inclusi i suoi operatori di confronto. In uno script di shell, i caratteri < e > dovevano essere citati per proteggerli dalla shell, ad es. if expr 1 \< 2; … è equivalente a if test 1 -lt 2; …. Laggiunta di espressioni aritmetiche alla shell ha reso obsoleta la maggior parte degli usi di expr, quindi non è “t ben noto oggi.

In uno script sh, tu” d generalmente utilizza espressioni aritmetiche per calcolare un valore intero e [ … ] per confrontare numeri interi.

if [ "$((x + y))" -lt "$z" ]; then … 

In un ksh , bash o zsh, puoi utilizzare ((…)) per entrambi.

if ((x + y < z)); then … 

Il [[ … ]] è utile se desideri utilizzare condizionali che coinvolgono cose diverse dagli interi.

Risposta

Secondo la pagina man di test, = e! = sono usati per confronti di stringhe mentre le espressioni -eq, -gt, -lt, -ge, -le e -ne sono confronti di interi. Ho sempre seguito questa convenzione durante la scrittura di script di shell e funziona sempre. Tieni presente che se hai variabili nellespressione, potresti dover citare le variabili in qualche modo per evitare di fare un confronto nullo.

Sulla carta, facciamo confronti tra stringhe e numeri senza pensarci troppo: un computer invece non sa se 987 è un numero o una stringa di caratteri. Hai bisogno che i diversi operatori dicano al computer cosa fare in modo da ottenere il risultato giusto. Ci sono alcune informazioni aggiuntive qui che spiegano parte della cronologia. Essenzialmente, le variabili non sono tipizzate e sono rimaste tali per compatibilità storica.

Commenti

  • Nel mio post, = e != sono operatori aritmetici, mentre la pagina man di test mostra solo operatori di espressioni condizionali.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *