Hur jämför jag siffror i bash?

Jag har det här skriptet, men det fungerar inte. Det beror på att det misslyckas med att utvärdera taljämförelsen i if-uttalandet, tror jag.

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

Hur kan jag fixa det här?

Kommentarer

  • Använd korrekta numeriska jämförelser – -eq för lika, etc.
  • Om du ' är nöjda med ett eller flera av svaren, röst upp dem. Om någon löser problemet skulle acceptera det vara det bästa sättet att säga " Tack! " Att acceptera ett svar indikerar också för framtida läsare att svaret faktiskt löste problemet.

Svar

Det finns flera problem med skriptet:

  • bash testerna görs antingen med test, [ .. ] eller [[ .. ]]; ( .. ) betyder underskal

  • Uppgift görs utan mellanslag, x = 1920 ringer kommandot x med parametrarna = och 1920. Använd istället x=1920.

  • Variabelnamn måste föregås av ett dollartecken när du använder dem. Så == x är dåligt och == $x är bra. (Förutom inom aritmetiska utvärderingar eller utvidgningar: (( ... )) eller $(( ... )), tack till kommentar från Kusalananda ).

  • Siffrorna ska jämföras med -eq, = är för strängjämförelse. I ditt fall bör det också fungera eftersom siffrorna sannolikt kommer att lagras identiskt, men det är bättre att använda den begreppsmässigt korrekta operatören. == är en icke-standard motsvarande =.

  • Du bör vänja dig vid att dubbla citera variabler överallt när det är möjligt, vilket till exempel förhindrar globbing.

Jag fixar bara raderna från x = 1920, den fasta versionen är:

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

Kommentarer

  • Om din tredje punkt: Förutom inom aritmetiska utvärderingar eller utvidgningar: (( ... )) eller $(( ... )).

Svar

Som andra svar noterade, (...) anger subshell. Aritmetisk expansion är ((...)), så om bash ska du använda ((...)) eller [[, eller POSIXly [. (( kan användas så:

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

Observera dock att i fallet med [[, operatorn == indikerar mönstermatchning, det vill säga det är ingen aritmetisk jämförelse.

Alternativt, om du verkligen vill använda == operatör med POSIX-skal, kan man göra följande:

$ 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 

När det gäller POSIX-skal /bin/sh finns det ingen (( operatör, men det finns $((, som expanderar till resultatet av ett aritmetiskt uttryck. Jämförelseoperatörer inom det agerar på ett C-liknande sätt, där 1 indikerar ett riktigt resultat och 0 indikerar ett falskt resultat (i motsats till vanligt skalvägen , där 0 är framgång och icke-noll är misslyckande).

Svar

if(a == b) är inte rätt syntax för en heljämförelse. Dessutom åberopar du x utan att indikera att det är en variabel, så du (försöker) jämföra värdet av $WIDTH med bokstavssträngen x. Försök istället:

if [[ $WIDTH -eq $x ]] 

Kommentarer

  • Citera din variabel. Tilldelningen till x är lika buggy.
  • När jag citerar variabler i [[ [...] ]] konstruktioner får jag höra att jag behöver inte '. När jag inte ' t får jag höra att jag borde. Jag kan inte vinna.
  • -1 | För du har använt [[ .. ]] när det inte är nödvändigt. Vanligt testkommando bör användas i ett sådant fall.
  • @Vlastimil vad som helst för? Detta är ett bash-skript. Det finns ' ingen anledning att använda [ alls.
  • Om du ' använder bash, det finns bokstavligen ingen anledning att använda [ [...] ] -konstruktionen som är både en delmängd och mer benägen att fel på grund av PICNIC-problem.

Svar

Prova detta:

# 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 

Förklaring:

  1. I bash, placera inte mellanslag (ar) runt = tilldela värden; exempel x=123, inte x = 123.
  2. Jämför saker i bash, använd [[ .. ]].
  3. xdotool har redan getwindowgeometry --shell bash programmering.

Kommentarer

  • -1 | För du har använt eval och ` onödigt

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *