Hoe vergelijk ik getallen in bash?

Ik heb dit script, maar het werkt niet. Het is omdat het de nummervergelijking in de if-instructie niet kan evalueren, denk ik.

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

Hoe kan ik dit oplossen?

Opmerkingen

  • Gebruik de juiste numerieke vergelijkingen – -eq voor gelijk, etc.
  • Als je ' als u tevreden bent met een of meer van de antwoorden, stem ze dan op. Als u uw probleem oplost, accepteren zou de beste manier zijn om " Dankjewel te zeggen! " Het accepteren van een antwoord betekent voor toekomstige lezers ook dat het antwoord het probleem daadwerkelijk heeft opgelost.

Antwoord

Er zijn verschillende problemen met het script:

  • bash tests zijn ofwel gedaan met test, [ .. ] of [[ .. ]]; ( .. ) betekent sub-shell

  • Toewijzingen zijn gemaakt zonder spaties, x = 1920 roept het commando x aan met de parameters = en 1920. Gebruik in plaats daarvan x=1920.

  • Variabelenamen moeten worden voorafgegaan door een dollarteken wanneer u ze gebruikt. Dus == x is slecht en == $x is goed. (Behalve binnen rekenkundige evaluaties of uitbreidingen: (( ... )) of $(( ... )), dankzij commentaar van Kusalananda ).

  • Getallen moeten worden vergeleken met -eq, = is voor stringvergelijking. In jouw geval zou het ook moeten werken aangezien de getallen waarschijnlijk identiek worden opgeslagen, maar het is beter om de conceptueel correcte operator te gebruiken. == is een niet-standaard equivalent van =.

  • Je zou eraan moeten wennen om waar mogelijk variabelen dubbel aan te halen, wat bijvoorbeeld globbing voorkomt.

Ik “zal gewoon de regels repareren die beginnen vanaf x = 1920, de vaste versie is:

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

Opmerkingen

  • Over uw derde punt: behalve binnen rekenkundige evaluaties of uitbreidingen: (( ... )) of $(( ... )).

Antwoord

Zoals andere antwoorden hebben opgemerkt, (...) geeft een subschaal aan. Rekenkundige uitbreiding is ((...)), dus in het geval van bash zou je ((...)) of [[, of POSIXly [. De (( kan als volgt worden gebruikt:

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

Houd er echter rekening mee dat in het geval van [[, de == operator geeft patroonovereenkomst aan, dwz het is geen rekenkundige vergelijking.

Als alternatief, als je de == operator echt wilt gebruiken met POSIX shell, zou je het volgende kunnen doen:

$ 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 

In het geval van POSIX shell /bin/sh is er “geen (( operator, maar er is een $((, die wordt uitgebreid tot het resultaat van een rekenkundige uitdrukking. Vergelijkingsoperatoren daarin werken op een C-achtige manier, waarbij 1 een echt resultaat aangeeft en 0 een vals resultaat aangeeft (in tegenstelling tot de gebruikelijke shell-manier , waarbij 0 succes is en niet-nul is mislukking).

Antwoord

if(a == b) is niet de juiste syntaxis voor een vergelijking van gehele getallen. Bovendien roept u x aan zonder aan te geven dat het een variabele is, dus u (probeert) de waarde van $WIDTH met de letterlijke tekenreeks x. Probeer in plaats daarvan:

if [[ $WIDTH -eq $x ]] 

Reacties

  • Citeer uw variabele. De toewijzing aan x is net zo foutief.
  • Als ik variabelen citeer in [[ [...] ]] constructies, krijg ik te horen dat ik hoef ' niet. Als ik het niet ' t, krijg ik te horen dat ik dat moet doen. Ik kan niet winnen.
  • -1 | Je hebt namelijk [[ .. ]] gebruikt als het niet nodig was. In zon geval moet een gewoon testcommando worden gebruikt.
  • @Vlastimil waar dan ook voor? Dit is een bash-script. Er is ' s geen reden om [ helemaal te gebruiken.
  • Als je ' bij het gebruik van bash, is er letterlijk geen reden om ooit de [ [...] ] -constructie te gebruiken die zowel een subset is als vatbaarder voor storing vanwege PICNIC-problemen.

Antwoord

Probeer dit:

# 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 

Uitleg:

  1. Plaats in bash geen spatie (n) rond = wanneer waarden toekennen; voorbeeld x=123, niet x = 123.
  2. Dingen vergelijken in bash, gebruik [[ .. ]].
  3. xdotool heeft al getwindowgeometry --shell voor bash programmeren.

Reacties

  • -1 | Want je hebt eval en ` onnodig gebruikt

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *