¿Cómo comparo números en bash?

Tengo este script, pero no funciona. Creo que se debe a que no se evalúa la comparación de números en la declaración if.

#!/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 

¿Cómo puedo solucionar este problema?

Comentarios

  • Use comparaciones numéricas adecuadas – -eq para igual, etc.
  • Si ' Si estás contento con una o varias de las respuestas, dale un voto positivo. Si uno está resolviendo su problema, aceptarlo sería la mejor manera de decir " ¡Gracias! " Aceptar una respuesta también indica a los futuros lectores que la respuesta realmente resolvió el problema.

Respuesta

Hay varios problemas con el script:

  • bash las pruebas están hechas con test, [ .. ] o [[ .. ]]; ( .. ) significa sub-shell

  • Las asignaciones se realizan sin espacios, x = 1920 llamará al comando x con los parámetros = y 1920. Utilice x=1920 en su lugar.

  • Los nombres de las variables deben ir precedidos de un signo de dólar cuando los utilice. Entonces == x es malo y == $x es bueno. (Excepto en evaluaciones aritméticas o expansiones: (( ... )) o $(( ... )), gracias al comentario de Kusalananda ).

  • Los números deben compararse con -eq, = es para comparar cadenas. En su caso, también debería funcionar, ya que es probable que los números se almacenen de manera idéntica, pero es mejor usar el operador conceptualmente correcto. == es un equivalente no estándar de =.

  • Debería acostumbrarse a las variables entre comillas dobles en todas partes cuando sea posible, lo que evita el globbing, por ejemplo.

Solo arreglaré las líneas a partir de x = 1920, la versión fija es:

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

Comentarios

  • Acerca de su tercer punto: excepto dentro de evaluaciones aritméticas o expansiones: (( ... )) o $(( ... )).

Responder

Como se indica en otras respuestas, (...) indica subshell. La expansión aritmética es ((...)), por lo que en el caso de bash debería usar ((...)) o [[ o POSIXly [. El (( se puede utilizar de la siguiente manera:

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

Sin embargo, tenga en cuenta que en el caso de [[, el operador == indica coincidencia de patrones, es decir, no es una comparación aritmética.

Alternativamente, si realmente desea utilizar el operador == con el shell POSIX, puede hacer lo siguiente:

$ 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 

En el caso del shell POSIX /bin/sh no hay operador ((, sin embargo, hay $((, que se expande al resultado de una expresión aritmética. Los operadores de comparación dentro de ella actúan en forma de C, donde 1 indica un resultado verdadero y 0 indica un resultado falso (a diferencia de la forma habitual de shell , donde 0 es éxito y no cero es fracaso).

Respuesta

if(a == b) no es la sintaxis adecuada para una comparación de enteros.Además, invoca x sin indicar que es una variable, por lo que está (intentando) comparar el valor de $WIDTH con la cadena literal x. Prueba en su lugar:

if [[ $WIDTH -eq $x ]] 

Comentarios

  • Cite su variable. La asignación a x es igual de defectuosa.
  • Cuando cito variables en [[ [...] ]] construcciones, me dicen que no ' no tiene que hacerlo. Cuando no ' t, me dicen que debería hacerlo. No puedo ganar.
  • -1 | Porque ha utilizado [[ .. ]] cuando no es necesario. En tal caso, debe usarse un comando de prueba ordinario.
  • @Vlastimil ¿para qué? Este es un script bash. ' no hay razón para usar [ en absoluto.
  • Si ' Al usar bash, literalmente no hay razón alguna para usar la construcción [ [...] ] que es tanto un subconjunto como más propensa a falla debido a problemas PICNIC.

Respuesta

Intente esto:

# 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 

Explicación:

  1. En bash, no coloque espacios alrededor de = cuando asignar valores; ejemplo x=123, no x = 123.
  2. Para comparar cosas en bash, use [[ .. ]].
  3. xdotool ya tiene getwindowgeometry --shell para bash programación.

Comentarios

  • -1 | Porque ha usado eval y ` innecesariamente

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *