Cum compar numerele din bash?

Am acest script, dar nu funcționează. Cred că nu reușește să evalueze comparația numărului în declarația 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 

Cum pot remedia acest lucru?

Comentarii

  • Folosiți comparații numerice adecvate – -eq pentru egal etc.
  • Dacă ' sunteți mulțumit de unul sau mai multe dintre răspunsuri, susțineți-le. Dacă cineva vă rezolvă problema, acceptarea acesteia ar fi cel mai bun mod de a spune " Vă mulțumim! " Acceptarea unui răspuns indică și cititorilor viitori că răspunsul a rezolvat de fapt problema.

Răspunsul

Există mai multe probleme cu scriptul:

  • bash testele sunt fie făcute cu test, [ .. ] sau [[ .. ]] ( .. ) înseamnă sub-shell

  • Atribuirea se face fără spații, x = 1920 va apela comanda x cu parametrii = și 1920. Folosiți în schimb x=1920.

  • Numele variabilelor trebuie să fie prefixate cu un semn de dolar atunci când le utilizați. Deci, == x este rău și == $x este bun. (Cu excepția evaluărilor sau extinderilor aritmetice: (( ... )) sau $(( ... )), datorită comentariilor făcute de Kusalananda ).

  • Numerele ar trebui comparate cu -eq, = este pentru compararea șirurilor. În cazul dvs. ar trebui să funcționeze, de asemenea, deoarece numerele sunt probabil stocate identic, dar este mai bine să utilizați operatorul corect din punct de vedere conceptual. == este un echivalent non-standard cu =.

  • Ar trebui să vă obișnuiți cu citarea dublă a variabilelor oriunde, când este posibil, ceea ce împiedică, de exemplu, blocarea.

Voi corecta doar liniile care încep de la x = 1920, versiunea fixă este:

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

Comentarii

  • Despre al treilea punct: cu excepția evaluărilor sau extinderilor aritmetice: (( ... )) sau $(( ... )).

Răspuns

După cum s-au observat și alte răspunsuri, (...) indică sub-coajă. Extinderea aritmetică este ((...)), deci în cazul bash ar trebui să utilizați ((...)) sau [[ sau POSIXly [. (( poate fi folosit ca atare:

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

Rețineți totuși că, în cazul [[, operatorul == indică potrivirea modelului, adică nu este o comparație aritmetică.

Alternativ, dacă doriți cu adevărat să utilizați operatorul == cu shell POSIX, puteți face următoarele:

$ 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 cazul shell-ului POSIX /bin/sh nu există operator ((, totuși există $((, care se extinde la rezultatul unei expresii aritmetice. Operatorii de comparație din interior acționează într-un mod asemănător cu C, unde 1 indică un rezultat adevărat, iar 0 indică un rezultat fals (spre deosebire de modul shell obișnuit , unde 0 este succes și non-zero este eșec).

Răspuns

if(a == b) nu este sintaxa adecvată pentru o comparație întregi În plus, invocați x fără a indica faptul că este o variabilă, deci (încercați) să comparați valoarea $WIDTH cu șirul literal x. Încercați în schimb:

if [[ $WIDTH -eq $x ]] 

Comentarii

  • Citați variabila dvs. Atribuirea către x este la fel de buggy.
  • Când citez variabile în [[ [...] ]], mi se spune că nu trebuie ' Când nu ' t, mi se spune că ar trebui. Nu pot câștiga.
  • -1 | Pentru că ați folosit [[ .. ]] atunci când nu este necesar. Comanda de testare obișnuită ar trebui utilizată într-un astfel de caz.
  • @Vlastimil pentru ce? Acesta este un script bash. Nu există ' niciun motiv pentru a utiliza [ deloc.
  • Dacă ' utilizând bash, literalmente nu există niciun motiv să folosiți constructul [ [...] ] care este atât un subset cât și mai predispus la eșec din cauza problemelor PICNIC.

Răspuns

Încercați acest lucru:

# 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 

Explicație:

  1. În bash, nu puneți spațiu în jurul = când atribuirea valorilor; exemplu x=123, nu x = 123.
  2. Pentru a compara lucrurile din bash, utilizați [[ .. ]].
  3. xdotool are deja getwindowgeometry --shell pentru bash programare.

Comentarii

  • -1 | Pentru că ați folosit eval și ` în mod inutil

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *