Por que minha declaração if interpreta um booleano para trás?

0

Estou realmente confuso sobre como a saída de algumas funções no meu .zshrc.

function __isred {
  if [[ $(ps cax | grep redshift | wc -l) > 0 ]]
  then
    return 1
  else
    return 0
  fi
}

function __togred {
  if __isred
  then
    killall redshift
  else
    redshift &
  fi
} 

A ideia com __isred é que se redshift estiver em execução, ele retornará true e false caso contrário. Eu posso confirmar que retorna a saída correta usando echos. No entanto, quando a saída é 1, a instrução if no __togred vai para o bloco else em vez do then. Há algo que estou perdendo aqui?

    
por Varlathass 20.06.2017 / 16:01

2 respostas

2

Para comandos shell, um status de saída 0 significa verdadeiro / sucesso e qualquer outra coisa significa falso / falha (com o valor exato sendo usado para discriminar entre diferentes tipos de falhas). O melhor aqui seria evitar usar valores de status de saída exatos e usar os comandos false ou true :

__isred() {
  if [[ $(ps cax | grep redshift | wc -l) > 0 ]]
  then
    true
  else
    false
  fi
}

Nesse ponto, você está começando a perceber que é um pouco bobo, como você pode fazer:

__isred() [[ $(ps cax | grep redshift | wc -l) > 0 ]]

Observe que [[ > ]] é para comparação lexical. Seria mais sensato usar a comparação numérica aqui:

__isred() (( $(ps cax | grep redshift | wc -l) > 0 ))

Mas, na verdade, não há necessidade de contar o número de ocorrências se você quiser apenas verificar se houve pelo menos um:

__isred() { ps cax | grep -q redshift; }

Deve ser o suficiente. grep retornará sucesso se a regex for correspondida.

Agora, enquanto estiver usando a sintaxe ps não padrão, convém usar o comando pgrep um pouco mais portátil para fazer isso ps + grep com mais facilidade e confiabilidade:

__isred() { pgrep redshift > /dev/null; }
    
por 20.06.2017 / 16:14
0

De zsh manual:

if list then list [ elif list then list ] ... [ else list ] fi    
    The if list is executed, and if it returns a zero exit status, the then list is executed.
    Otherwise, the elif list is executed and if its status is zero, the then list is executed.
    If each elif list returns nonzero status, the else list is executed.

Em um sistema unix, por convenção, um valor de retorno de 0 representa sucesso. Isso é contra-intuitivo, mas faz sentido porque permite que os comandos usem diferentes valores de retorno para diferentes erros.

    
por 20.06.2017 / 16:18

Tags