Erreur dans la boucle while pour vérifier l’existence du fichier uniquement à une heure fixe

J’ai besoin d’écrire une boucle while pour vérifier l’existence d’un fichier.

Mon exigence est la suivante: vérifiez le fichier uniquement pendant 5 minutes. Si le fichier arrive dans ce chemin dans les 5 minutes, quittez la boucle et continuez le rest du script, sinon quittez le script après 5 minutes avec une erreur “fichier introuvable”. J’ai écrit le code comme ceci:

SOURCEFILE=/path/*file.csv StartTime=$(date +'%s') TimeSpan=300 EndTime=$((StartTime + TimeSpan)) while [[ ! -f ${SOURCEFILE} && $(date +'%s') < ${EndTime} ]] do echo "inside loop" sleep 25 done echo "outside loop" 

Mais avec cette boucle while, même si le fichier est présent dans le chemin mentionné, il passe en boucle et ne sortira qu’après 300 secondes. Je suis débutant en script shell et je ne suis pas capable de comprendre le problème. J’utilise ksh.

Je pourrais aussi vous dire que cela fonctionne trouver avec while [ ! -f {SOURCEFILE} ] while [ ! -f {SOURCEFILE} ] uniquement. Mais chaque fois que j’ajoute une condition && à la boucle while, alors -f ne fonctionne pas correctement.

Le SOURCEFILE=/path/*file.csv est incorrect dans votre cas. Il ne peut pas être évalué correctement avec le drapeau -f .

Une solution simple serait d’utiliser find ou ls et de compter le résultat:

 find /path/ -name "*file.csv" -type f # then count the result... 

Maintenant, je pense qu’il y a un problème de logique avec la priorité des opérateurs. Pour forcer l’évaluation du ! pour le -f uniquement, utilisez des parenthèses. Voici ce qui fonctionne pour moi, et vous devez l’adapter un peu pour correspondre au * avant le file.csv :

 while [[ ( ! -f file.csv ) && $(date +'%s') < ${EndTime} ]] do echo "inside loop" sleep 25 ... 

Il y a plus d'explications sur cette réponse . L'opérateur "and" précède le "not", c'est pourquoi vous avez eu le problème.

Votre principal problème est de faire en sorte que l’astérisque ( * ) se développe au bon moment.

Cela n’aide pas que les constructions [ ] et [[ ]] se comportent différemment, surtout quand / quand développer cet astérisque. [Vous pouvez parcourir la recherche google pour «ksh single bracket vs double bracket» pour plus de détails.]

Essayez d’exécuter ce qui suit pour voir les différences entre les crochets simples / doubles et les variables non cotées / entre guillemets / entre guillemets:

 SOURCEFILE=/path/*file.csv set -x [ ! -f ${SOURCEFILE} ] && echo 'missing' [ ! -f '${SOURCEFILE}' ] && echo 'missing' [ ! -f "${SOURCEFILE}" ] && echo 'missing' [[ ! -f ${SOURCEFILE} ]] && echo 'missing' [[ ! -f '${SOURCEFILE}' ]] && echo 'missing' [[ ! -f "${SOURCEFILE}" ]] && echo 'missing' 

Remarque: notez quels tests développent l’astérisque et qui recherchent un astérisque (littéral) dans le nom.

REMARQUE: Essayez d’append un espace à votre nom de fichier (par exemple, *file XX.csv ) et exécutez les tests ci-dessus … délicate, délicate, délicate …

Pour ce cas particulier … astérisque / joker dans le nom du fichier, pas d’espaces, ksh … vous serez probablement d’accord avec quelque chose comme:

 while [[ ! -f ${SOURCEFILE} ]] && [[ $(date +'%s') < ${EndTime} ]]