Jak mohu porovnat čísla v bash?

Mám tento skript, ale nefunguje. Je to proto, že se mi nedaří vyhodnotit srovnání čísel v příkazu if. Myslím, že.

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

Jak to mohu opravit?

Komentáře

  • Použijte správná numerická srovnání – -eq pro rovnocenné atd.
  • Pokud ' máte radost z jedné nebo několika odpovědí, hlasujte pro ně. Pokud někdo váš problém řeší, jeho přijetí by byl nejlepší způsob, jak říci " Děkuji! " Přijetí odpovědi také budoucím čtenářům naznačuje, že odpověď problém skutečně vyřešila.

Odpověď

Skript má několik problémů:

  • bash testy jsou buď hotové s test, [ .. ] nebo [[ .. ]]; ( .. ) znamená dílčí prostředí

  • Přiřazení se provádí bez mezer, x = 1920 zavolá příkaz x s parametry = a 1920. Místo toho použijte x=1920.

  • Když použijete názvy proměnných, musí před nimi být znak dolaru. == x je tedy špatný a == $x dobrý. (S výjimkou aritmetických hodnocení nebo rozšíření: (( ... )) nebo $(( ... )), díky komentáři Kusalananda ).

  • Čísla by měla být porovnávána s -eq, = je pro porovnání řetězců. Ve vašem případě by to také mělo fungovat, protože čísla budou pravděpodobně uložena shodně, ale je lepší použít koncepčně správný operátor. == je nestandardní ekvivalent k =.

  • Měli byste si zvyknout na zdvojnásobení uvozovek proměnných, kdykoli je to možné, což například brání globování.

Já jen opravím řádky počínaje x = 1920, pevná verze je:

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

Komentáře

  • O vašem třetím bodě: Kromě aritmetických hodnocení nebo rozšíření: (( ... )) nebo $(( ... )).

odpověď

Jak poznamenaly další odpovědi, (...) označuje subshell. Aritmetická expanze je ((...)), takže v případě bash byste měli používat ((...)) nebo [[ nebo POSIXly [. (( lze použít takto:

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

Upozorňujeme však, že v případě [[ operátor == označuje shodu vzorů, tj. Nejde o aritmetické srovnání.

Alternativně, pokud opravdu chcete použít operátor == s POSIX shell, můžete provést následující:

$ 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 

V případě prostředí POSIX shell /bin/sh neexistuje žádný (( operátor, existuje však $((, který se rozšíří na výsledek aritmetického výrazu. Operátory porovnání v něm fungují způsobem typu C, kde 1 označuje skutečný výsledek a 0 označuje falešný výsledek (na rozdíl od obvyklého způsobu prostředí , kde 0 je úspěch a nenulová selhání).

Odpověď

if(a == b) není správná syntaxe pro celočíselné srovnání Navíc vyvoláte x, aniž byste označili, že jde o proměnnou, takže se (snažíte) porovnávat hodnotu $WIDTH s doslovným řetězcem x. Zkuste místo toho:

if [[ $WIDTH -eq $x ]] 

Komentáře

  • Uveďte svou proměnnou. Přiřazení x je stejně chybné.
  • Když cituji proměnné v konstrukcích [[ [...] ]], řeknu mi nemusíte ' muset. Když ' t nedostanu, bylo mi řečeno, že bych měl. Nemohu vyhrát.
  • -1 | Použili jste [[ .. ]], pokud to není nutné. V takovém případě by měl být použit obyčejný testovací příkaz.
  • @Vlastimil pro cokoli? Toto je bash skript. ' Není důvod vůbec [ používat.
  • Pokud ' Při použití bash není doslova žádný důvod použít konstrukci [ [...] ], která je podmnožinou i náchylnější k selhání kvůli problémům PICNIC.

Odpověď

Zkuste toto:

# 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 

Vysvětlení:

  1. V bash nedávejte prostor kolem =, když přiřazování hodnot; příklad x=123, ne x = 123.
  2. Porovnání věcí v bash, použijte [[ .. ]].
  3. xdotool již getwindowgeometry --shell pro bash programování.

Komentáře

  • -1 | Protože jste použili eval a ` zbytečně

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *