AND lógico em um script bash

10

Eu tenho um ifno meu script bash que tem que verificar se existe um dos 2 arquivos, se eles não existem, deve ecoar.

Código que eu tenho:

if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Mas isso não parece funcionar por algum motivo.

Tenho 110% de certeza de que esses 2 arquivos não existem. Eu não recebo nenhum erro, ele simplesmente não entra no arquivo if.

Eu sou novo no bash scripting, então não tenho certeza do que pode estar errado.

Peppercat101
fonte
Acho que nenhuma das respostas postadas realmente aborda a questão. O que acontece quando você tenta os testes individualmente? Faça [[ ! -f /etc/.../... ]]; echo $?para cada um.
jw013
Um aviso : [[ -f xxx ]]retorna true se xxx existir e for um arquivo regular (ou um link simbólico para um arquivo regular). Ele retornará false se não existir, ou se não puder dizer se existe ou se existe, mas não é um arquivo comum (diretório, canal, dispositivo, soquete ...) ou se é um link simbólico para um arquivo que não existe ou não pode dizer se existe ou não ou não é um arquivo normal ... [[ -e $file ]] || [[ -L $file ]]está mais perto de um teste de existência. ls -d -- "$file" > /dev/null 2>&1está ainda mais perto. E, como regra, esse tipo de teste leva a condições de corrida. Talvez haja outro caminho.
Stéphane Chazelas

Respostas:

12

Se você quer , então você quer OR, não AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Isso corresponderá se um ou ambos os arquivos estiverem ausentes.
  • Seu código será impresso apenas matchse ambos não existirem.

Mas você disse:

Tenho 110% de certeza de que esses 2 arquivos não existem. Eu não recebo nenhum erro, ele simplesmente não entra no if.

Portanto, sua afirmação se contradiz. Pelo menos um desses arquivos deve existir, se você estiver executando esse código.

Se você quiser ver como sua ifdeclaração está sendo avaliada, execute-a com -x.

#!/bin/bash -x
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Então você verá a execução.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 
bahamat
fonte
Eu quero que ele ecoe "match" se nenhum arquivo existir, se existir, ele não será impresso. Vou tentar com -x
Peppercat101
Nesse caso, seu código original deve estar bem. E de fato funciona para mim.
bahamat 13/09/12
3

Isso não deveria ser assim? A é um arquivo ou B é um arquivo, então blabla.

if [[ -f /etc/benchmarking/code ]] || [[ -f /etc/benchmarking/code.class ]]; 
then  
  echo "match"
fi
margarida
fonte
3

Isso também pode funcionar para o que você está tentando fazer. Parênteses simples não são usados ​​hoje em dia com o bash, mas isso ainda é uma opção. Usar '-o' é efetivamente uma operação "OR" e "!" nega a condição.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"
slashdot
fonte
Nunca use [em bash. Além disso, não vejo como isso responde à pergunta.
jw013
[ ! -f ${var} -a ! -f {var}.class ] && echo "match"deveria ser. A missão era: se eles (ambos) não existem, deveriam existir echo match.
hschou 2/09/16
0

Seu código atende aos seus requisitos: será impresso, matchdesde que não encontre nenhum dos arquivos.

Portanto, o motivo matchnão está sendo impresso está em outro lugar. Você deve confirmar que o bloco de código está sendo alcançado, o que pode ser feito envolvendo-o com algumas mensagens de depuração. Por exemplo, assim:

echo '@ About to enter if...fi block'
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
echo '@ Finished if...fi block'

Minha preferência usual é a depuração de mensagens para o stderr , a fim de evitar a interrupção do fluxo de dados para o stdout , mas evitei isso aqui porque você disse que era iniciante. Aqui está um exemplo mostrando como você pode escrever para o stdout :

echo '@ About to enter if...fi block' >&2
roaima
fonte