(Ill) Declaração lógica

1

Eu estou tentando fazer um script simples para virar a tela do meu computador. Minha primeira instrução if é executada perfeitamente, mas depois disso, se o $ istouch estiver "on", o bloco de instrução elif não será executado! Eu tentei executar bash com a opção -u sem falha e tentei mudar as verificações, nada funciona.

#!/bin/bash
xsetwacom --set 16 touch False
istouch='xsetwacom --get 15 touch'
$istouch
if [ "$istouch"=="off" ]
then
    xrandr -o inverted
    xinput set-prop 13 'Coordinate Transformation Matrix' -1 0 1 0 -1 1 0 0 1
    xinput set-prop 15 'Coordinate Transformation Matrix' -1 0 1 0 -1 1 0 0 1
    xinput set-prop 16 'Coordinate Transformation Matrix' -1 0 1 0 -1 1 0 0 1
    xsetwacom --set 15 touch True

elif [ "$istouch"=="on" ]
then
    xrandr -o 0
    xinput set-prop 13 'Coordinate Transformation Matrix' 1 0 0 0 1 0 0 0 1
    xinput set-prop 15 'Coordinate Transformation Matrix' 1 0 0 0 1 0 0 0 1
    xinput set-prop 16 'Coordinate Transformation Matrix' 1 0 0 0 1 0 0 0 1
    xsetwacom --set 15 touch False
fi
    
por Timidger 24.09.2013 / 04:55

2 respostas

5

Seus if statments não estão sendo exibidos da maneira que você pensa. Você pode ativar a depuração de scripts Bash, incluindo o comando set -x e, em seguida, desativá-lo com set +x .

Exemplo

Então, primeiro adicionamos a depuração da seguinte forma:

#!/bin/bash

## DEBUG
set -x
xsetwacom --set 16 touch False
....

Eu então executo o seu script, chamei-o de ex.bash , então invoco-o:

$ ./ex.bash

Bash tenta executar esta linha:

if [ "$istouch"=="off" ]

E da saída, podemos ver que o Bash está ficando confuso. Está sendo executado com a string 'xsetwacom --get 15 touch==off' .

+ '[' 'xsetwacom --get 15 touch==off' ']'

Os argumentos para o == não devem ser tocados assim. Bash é notoriamente exigente em coisas como esta. Então coloque um pouco de espaço antes e depois assim:

 if [ "$istouch" == "off" ]
 elif [ "$istouch" == "on" ]

Agora, isso parece um pouco melhor:

+ '[' 'xsetwacom --get 15 touch' == off ']'
+ '[' 'xsetwacom --get 15 touch' == on ']'

No entanto, você não quer comparar o stirng $istouch , você quer comparar os resultados do comando que esta string representa, então mude o topo do script para isto:

....
xsetwacom --set 16 touch False
istouch=$(xsetwacom --get 15 touch)
if [ "$istouch" == "off" ]
....

Agora, estamos executando o comando xsetwacom e armazenando os resultados em $istouch . Eu não tenho esses dispositivos, então recebo uma mensagem sobre device 15 . Mas isso é o que o script faz agora:

++ xsetwacom --get 15 touch
+ istouch='Cannot find device '\''15'\''.'
+ '[' 'Cannot find device '\''15'\''.' == off ']'
+ '[' 'Cannot find device '\''15'\''.' == on ']'

Espero que isso lhe dê uma ideia:

  1. Como depurar seu script
  2. Melhor compreensão da sintaxe de Bash

Veja mais detalhadamente as declarações if

Você pode ficar se perguntando por que a declaração if sequer combinou. O problema é que se você der ao comando [ uma única string, ele tratará isso como uma verdade se a string não estiver vazia, e a instrução if cairá na sua seção then .

Exemplo

$ [ "no"=="yes" ] && echo "they match"
they match

$ [ "notheydont"=="yes" ] && echo "they match"
they match

Pode parecer que existe uma verificação de igualdade ocorrendo aqui, mas não existe. [ some-string ] é a abreviação de [ -n some-string ] , que é um teste para que alguma cadeia seja [n] vazia. Usando set -x nos mostra isto:

$ set -x; [ "notheydont"=="yes" ] && echo "they match"; set +x
+ '[' notheydont==yes ']'
+ echo 'they match'
they match
+ set +x

Se colocarmos algum espaço entre os argumentos para a verificação de igualdade:

# fails
$ set -x; [ "notheydont" == "yes" ] && echo "they match"; set +x
+ '[' notheydont == yes ']'
+ set +x

# passes
$ set -x; [ "yes" == "yes" ] && echo "they match"; set +x
+ set -x
+ '[' yes == yes ']'
+ echo 'they match'
they match
+ set +x

Agora funciona como esperado!

    
por 24.09.2013 / 05:12
0

substituir

istouch='xsetwacom --get 15 touch'
$istouch

com (observe as aspas traseiras):

istouch='xsetwacom --get 15 touch'
    
por 24.09.2013 / 06:29