Logico AND in uno script bash


10

Ho uno ifscript nel mio bash che deve verificare se ESSO dei 2 file esiste, se non esistono dovrebbe corrispondere all'eco.

Codice che ho:

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

Ma questo non sembra funzionare per qualche motivo.

Sono sicuro al 110% che questi 2 file non esistono. Non ricevo errori, semplicemente non entra in if.

Sono nuovo di bash scripting quindi non sono sicuro di cosa potrebbe essere sbagliato.


Non penso che nessuna delle risposte pubblicate in realtà risponda alla domanda. Cosa succede quando provi i test individualmente? Fare [[ ! -f /etc/.../... ]]; echo $?per ciascuno.
jw013,

Un avvertimento : [[ -f xxx ]]restituisce vero se xxx esiste ed è un file normale (o un collegamento simbolico a un file normale). Restituirà falso se non esiste, o se non può dire se esiste o no o se esiste ma non è un file normale (directory, pipe, dispositivo, socket ...) o se è un link simbolico a un file che non esiste o non può dire se esiste o no o non è un file normale ... [[ -e $file ]] || [[ -L $file ]]è più vicino a un test per l'esistenza. ls -d -- "$file" > /dev/null 2>&1è ancora più vicino. E di norma, questo tipo di test porta a condizioni di gara. Forse c'è un altro modo.
Stéphane Chazelas,

Risposte:


12

Se vuoi uno, allora vuoi OR, no AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Ciò corrisponderà se mancano uno o entrambi i file.
  • Il codice verrà stampato solo matchse entrambi non esistono.

Ma hai detto:

Sono sicuro al 110% che questi 2 file non esistono. Non ricevo errori, semplicemente non inserisce l'if.

Quindi la tua affermazione si contraddice. Almeno uno di questi file deve esistere, se si esegue quel codice.

Se vuoi vedere come ifsta valutando la tua dichiarazione, eseguila -x.

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

Quindi vedrai l'esecuzione.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 

Voglio che risuoni "match" se nessuno dei file esiste, se ne esiste uno, non stampa la corrispondenza. Lo proverò con -x
Peppercat101 il

In tal caso, il codice originale dovrebbe andare bene. E davvero funziona per me.
bahamat,

3

Non dovrebbe essere così? A è un file o B è un file, quindi blabla.

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

3

Questo potrebbe funzionare anche per quello che stai cercando di fare. Le parentesi singole non sono comunemente utilizzate oggi con bash, ma questa è ancora un'opzione. L'uso di '-o' è effettivamente un'operazione "OR" e "!" nega la condizione.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"

Non utilizzare mai [in bash. A parte questo, non riesco a vedere come questo risponda alla domanda.
jw013,

[ ! -f ${var} -a ! -f {var}.class ] && echo "match"dovrebbe essere. La ricerca era: se (entrambi) non esistono, dovrebbe echo match.
hschou,

0

Il tuo codice soddisfa i tuoi requisiti: verrà stampato a matchcondizione che non riesca a trovare nessuno dei due file.

Pertanto il motivo per cui matchnon viene stampato è altrove. Dovresti confermare che il blocco di codice è stato raggiunto, cosa che puoi fare circondandolo con un paio di messaggi di debug. Ad esempio, in questo modo:

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'

La mia solita preferenza è che i messaggi di debug vadano su stderr in modo da evitare di interrompere il flusso di dati su stdout , ma l'ho evitato qui perché hai detto che eri un principiante. Ecco un esempio che mostra come scrivere su stdout :

echo '@ About to enter if...fi block' >&2
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.