2

I have got this script, but it is not working. It is because it is failing to evaluate the number comparison in the if statement, I think.

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

How can I fix this?

2
  • Use proper numeric comparisons - -eq for equal, etc.
    – ivanivan
    Commented Jan 30, 2018 at 19:28
  • If you're happy with one or several of the answers, upvote them. If one is solving your issue, accepting it would be the best way of saying "Thank You!" Accepting an answer also indicates to future readers that the answer actually solved the problem.
    – Kusalananda
    Commented Feb 7, 2018 at 10:58

4 Answers 4

10

There are several issues with the script:

  • bash tests are either done with test, [ .. ] or [[ .. ]]; ( .. ) means sub-shell

  • Assignment are made without spaces, x = 1920 will call the command x with the parameters = and 1920. Use x=1920 instead.

  • Variable names need to be prefixed with a dollar sign when you use them. So == x is bad and == $x is good. (Except within arithmetic evaluations or expansions: (( ... )) or $(( ... )), thanks to comment by Kusalananda).

  • Numbers should be compared with -eq, = is for string comparison. In your case it should also work since the numbers are likely to be stored identically, but it's better to use the conceptually correct operator. == is a non-standard equivalent to =.

  • You should get used to double quoting variables everywhere when possible, which prevents globbing for instance.

I'll just fix the lines starting from x = 1920, the fixed version is:

x=1920
if [ "$WIDTH" -eq "$x" ]
then
    wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz 
else 
    xdotool key Ctrl+F12
fi
1
  • 1
    About your third point: Except within arithmetic evaluations or expansions: (( ... )) or $(( ... )).
    – Kusalananda
    Commented Jan 31, 2018 at 6:36
2

if(a == b) is not the proper syntax for an integer comparison Additionally, you invoke x without indicating it to be a variable, so you are (trying to) compare the value of $WIDTH with the literal string x. Try instead:

if [[ $WIDTH -eq $x ]]
5
  • Quote your variable. The assignment to x is just as buggy. Commented Jan 30, 2018 at 19:29
  • 2
    When I quote variables in [[ [...] ]] constructs, I get told I don't have to. When I don't, I get told I should. I cannot win.
    – DopeGhoti
    Commented Jan 30, 2018 at 19:31
  • -1 | For you have used [[ .. ]] when not necessary. Ordinary test command should be used in such a case. Commented Jan 31, 2018 at 8:19
  • 1
    @Vlastimil whatever for? This is a bash script. There's no reason to use [ at all.
    – muru
    Commented Jan 31, 2018 at 8:55
  • 1
    If you're using bash, there is literally no reason ever to use the [ [...] ] construct which is both a subset and more prone to failure due to PICNIC issues.
    – DopeGhoti
    Commented Jan 31, 2018 at 15:43
2

As other answers noted, (...) indicates subshell. Arithmetic expansion is ((...)), so in case of bash you should be using ((...)) or [[, or POSIXly [. The (( can be used as so:

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

Note, however, that in case of [[, the == operator indicates pattern matching, i.e. it is not arithmetic comparison.

Alternatively, if you really want to use == operator with POSIX shell, one could do the following:

$ 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 case of POSIX shell /bin/sh there's no (( operator, however there is $((, which expands to the result of an arithmetic expression. Comparison operators within it act in a C-like manner, where 1 indicates a true result, and 0 indicates a false result (as opposed to usual shell way, where 0 is success and non-zero is failure).

-1

Try this:

# 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

Explanation:

  1. In bash, do not put space(s) arround = when assigning values; example x=123, not x = 123.
  2. To compare things in bash, use [[ .. ]].
  3. xdotool already has getwindowgeometry --shell for bash programming.
1
  • -1 | For you have used eval and ` unnecessarilly Commented Jan 31, 2018 at 8:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .