Come si confrontano i numeri in bash?

Ho questo script, ma non funziona. È perché non riesce a valutare il confronto dei numeri nellistruzione if, credo.

#!/bin/bash { read __ WIDTH; read __ HEIGHT; read __ __ BORDER_WIDTH; } < <(xwininfo -id "$(xdotool getactivewindow)" | grep -o -e "Height:.*" -e "Width:.*" -e "Border width:.*") echo "Height: $HEIGHT, Width: $WIDTH, Border width: $BORDER_WIDTH" x = 1920 if($WIDTH == x) then wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz else xdotool key Ctrl+F12 fi 

Come posso risolvere questo problema?

Commenti

  • Utilizza confronti numerici appropriati – -eq per uguale, ecc.
  • Se ' sei soddisfatto di una o più risposte, votale a favore. Se qualcuno sta risolvendo il tuo problema, accettarlo sarebbe il modo migliore per dire " Grazie! " Accettare una risposta indica anche ai lettori futuri che la risposta ha effettivamente risolto il problema.

Risposta

Ci sono diversi problemi con lo script:

  • bash vengono eseguiti i test con test, [ .. ] o [[ .. ]]; ( .. ) significa sottostruttura

  • Le assegnazioni vengono effettuate senza spazi, x = 1920 chiamerà il comando x con i parametri = e 1920. Utilizza invece x=1920.

  • I nomi delle variabili devono essere preceduti dal simbolo del dollaro quando li utilizzi. Quindi == x è sbagliato e == $x è buono. (Tranne che allinterno di valutazioni aritmetiche o espansioni: (( ... )) o $(( ... )), grazie al commento di Kusalananda ).

  • I numeri devono essere confrontati con -eq, = è per il confronto tra stringhe. Nel tuo caso dovrebbe funzionare anche perché è probabile che i numeri siano memorizzati in modo identico, ma è meglio usare loperatore concettualmente corretto. == è un equivalente non standard di =.

  • Dovresti abituarti a doppiare le variabili ovunque quando possibile, il che impedisce ad esempio il globbing.

Correggerò solo le righe che iniziano da x = 1920, la versione corretta è:

x=1920 if [ "$WIDTH" -eq "$x" ] then wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz else xdotool key Ctrl+F12 fi 

Commenti

  • Informazioni sul terzo punto: tranne allinterno di valutazioni aritmetiche o espansioni: (( ... )) o $(( ... )).

Risposta

Come notato da altre risposte, (...) indica una subshell. Lespansione aritmetica è ((...)), quindi in caso di bash dovresti utilizzare ((...)) o [[ o POSIXly [. (( può essere utilizzato in questo modo:

$ if ((1==1)); then echo "YES" ;fi YES 

Nota, tuttavia, che in caso di [[, loperatore == indica la corrispondenza del modello, ovvero non è un confronto aritmetico.

In alternativa, se vuoi davvero usare loperatore == con la shell POSIX, puoi fare quanto segue:

$ foo=1 $ bar=2 $ if [ $((foo==bar)) -eq 1 ]; then echo "YES"; else echo "NO"; fi NO $ bar=1 $ if [ $((foo==bar)) -eq 1 ]; then echo "YES"; else echo "NO"; fi YES 

Nel caso della shell POSIX /bin/sh non esiste un operatore ((, tuttavia esiste $((, che si espande al risultato di unespressione aritmetica. Gli operatori di confronto al suo interno agiscono in modo simile al C, dove 1 indica un risultato vero e 0 indica un risultato falso (al contrario del solito modo di shell , dove 0 è successo e diverso da zero è fallimento).

Risposta

if(a == b) non è la sintassi corretta per un confronto di numeri interi Inoltre, si richiama x senza indicare che si tratta di una variabile, quindi si sta (tentando di) confrontare il valore di $WIDTH con la stringa letterale x. Prova invece:

if [[ $WIDTH -eq $x ]] 

Commenti

  • Cita la tua variabile. Lassegnazione a x è altrettanto difettosa.
  • Quando cito variabili nei costrutti [[ [...] ]], mi viene detto che non ' necessario. Quando non ' t, mi viene detto che dovrei. Non posso vincere.
  • -1 | Perché hai utilizzato [[ .. ]] quando non è necessario. In tal caso dovrebbe essere usato il comando di test ordinario.
  • @Vlastimil per quale motivo? Questo è uno script bash. ' non cè alcun motivo per utilizzare [.
  • Se ' utilizzando bash, non cè letteralmente alcun motivo per usare il costrutto [ [...] ] che è sia un sottoinsieme che più incline a errore dovuto a problemi PICNIC.

Risposta

Prova questo:

# use xrandr+sed to get current screen width screenWidth=`xrandr|sed -En "/connected [0-9]+x[0-9]+/{s/^.*connected ([0-9]+)x[0-9]+.*$/\1/;p}"` # use xdotool getwindowgeometry --shell to get size/pos of window eval `xdotool getactivewindow getwindowgeometry --shell` echo $screenWidth $WIDTH # debug, to see values got from xrandr and xdotool if [[ $WIDTH = $screenWidth ]]; then wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz else xdotool key Ctrl+F12 fi 

Spiegazione:

  1. In bash, non inserire spazi intorno a = quando assegnare valori; esempio x=123, non x = 123.
  2. Per confrontare le cose in bash, utilizza [[ .. ]].
  3. xdotool ha già getwindowgeometry --shell per bash programmazione.

Commenti

  • -1 | Poiché hai utilizzato eval e ` inutilmente

Lascia un commento

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