Lógico Y en un script bash

10

Tengo un ifscript en mi bash que tiene que verificar si CUALQUIERA de los 2 archivos existe, si no existen debería hacer eco.

Código que tengo:

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

Pero esto no parece funcionar por alguna razón.

Estoy 110% seguro de que estos 2 archivos no existen. No recibo ningún error, simplemente no entra en el if.

Soy nuevo en bash scripting, así que no estoy seguro de qué podría estar mal.

Peppercat101
fuente
No creo que ninguna de las respuestas publicadas realmente aborde la pregunta. ¿Qué sucede cuando pruebas individualmente? Haz [[ ! -f /etc/.../... ]]; echo $?por cada uno.
jw013
Una advertencia : [[ -f xxx ]]devuelve verdadero si xxx existe y es un archivo normal (o un enlace simbólico a un archivo normal). Devolverá falso si no existe, o si no puede decir si existe o no o si existe pero no es un archivo normal (directorio, tubería, dispositivo, socket ...) o si es un enlace simbólico a un archivo que no existe o no puede decir si existe o no o no es un archivo normal ... [[ -e $file ]] || [[ -L $file ]]está más cerca de una prueba de existencia. ls -d -- "$file" > /dev/null 2>&1Está aún más cerca. Y, como regla, este tipo de prueba conduce a condiciones de carrera. Tal vez hay otra forma.
Stéphane Chazelas

Respuestas:

12

Si quieres cualquiera, entonces quieres OR, no AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Esto coincidirá si faltan uno o ambos archivos.
  • Su código solo se imprimirá matchsi ambos no existen.

Pero dijiste:

Estoy 110% seguro de que estos 2 archivos no existen. No recibo ningún error, simplemente no ingresa el if.

Entonces su afirmación se contradice a sí misma. Al menos uno de esos archivos debe existir, si está ejecutando ese código.

Si desea ver cómo ifse evalúa su declaración, ejecútela con -x.

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

Entonces verás la ejecución.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 
bahamat
fuente
Quiero que haga eco de "coincidencia" si ninguno de los archivos existe, si existe uno no imprime coincidencia. Lo intentaré con -x
Peppercat101
En ese caso, su código original debería estar bien. Y de hecho funciona para mí.
bahamat
3

¿No debería ser así? A es un archivo o B es un archivo, luego blabla.

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

Esto también puede funcionar para lo que está tratando de hacer. Los corchetes individuales no se usan comúnmente hoy en día con bash, pero esta sigue siendo una opción. Usar '-o' es efectivamente una operación "OR" y "!" niega la condición.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"
slashdot
fuente
No utilice nunca [en bash. Aparte de eso, no veo cómo esto responde la pregunta.
jw013
[ ! -f ${var} -a ! -f {var}.class ] && echo "match"debería ser. La búsqueda era: si ellos (ambos) no existen, debería echo match.
hschou
0

Su código satisface sus requisitos: se imprimirá matchsiempre que no pueda encontrar ninguno de los archivos.

Por lo tanto, la razón matchno se está imprimiendo está en otra parte. Debe confirmar que se está alcanzando el bloque de código, lo que puede hacer rodeándolo con un par de mensajes de depuración. Por ejemplo, así:

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'

Mi preferencia habitual es que los mensajes de depuración vayan a stderr para evitar interrumpir el flujo de datos a stdout , pero lo he evitado aquí porque dijiste que eras un principiante. Aquí hay un ejemplo que muestra cómo podría escribir en stdout :

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