Ho il seguente script che controlla se c'è un file in una cartella e se il file è stabile (questo è per file video di grandi dimensioni che sto ricevendo).
#!/bin/bash
cdate1=$(date +%Y%m%d-%T)
folder1="/path-to-folder"
cd $folder1
while file=$(ls "$folder1")
[ -z "$file" ]
do sleep 10
done
echo "There is a file in the folder at $cdate1"
size1=$(stat -c '%s' "$file")
echo "The size1 is $size1"
sleep 30
size2=$(stat -c '%s' "$file")
echo "The size2 is $size2"
if [ $size1 = $size2 ]
then
ls -l
echo "Start converting"
else
echo "Restart the script"
fi
Come modificare lo script in modo che possa controllare più file nella stessa cartella e dopo che tutti sono stabili per avviare lo script di conversione?
Risposta accettata:
ci sono una serie di problemi nel tuo script, a cominciare da:
folder1="path-to-folder"
cd $folder1
while file=$(ls "$folder1") ...
questo fa davvero cd path-to-folder; ls path-to-folder
; se path-to-folder
è assoluto (iniziando con '/' come nel tuo esempio) questo potrebbe funzionare, ma non funzionerà ogni volta che usi percorsi relativi.
non funzionerà nemmeno se path-to-folder
contiene spazi, poiché dovresti usare le virgolette ovunque, ad es. cd "$folder1"
quindi eseguendo un while file=$(ls ...)
farà un ciclo infinito, come file
sarà sempre impostato su qualcosa (il contenuto della directory).
la sintassi corretta sarebbe for file in $(ls ...)
, che smetterà di funzionare non appena avrai nomi di file con spazi (poiché il ciclo verrà eseguito su foo
e bar
se hai un file chiamato foo bar
). controlla perché non dovresti mai analizzare l'output di ls. invece di usare ls
potresti semplicemente fare for file in *
.
infine, potresti avere file che stanno cambiando anche se le dimensioni non cambiano più.
un buon modo per scorrere i file è find
comando; un buon modo per verificare se qualcosa è cambiato è mtime
di un file.
la seguente funzione fornisce un valore per l'ultima modifica (mtime) di qualsiasi file nella directory data
folder1="/path-to-folder"
find "${folder1}" -exec stat -c "%Y" \{\} \; \
| sort -n | tail -1
quindi il tuo script potrebbe assomigliare a:
#!/bin/bash
dir="$1"
# check whether $dir exists
test -d "${dir}" || exit 1
last=0
current=1
while [ "$last" != "$current" ]; do
last=$current
current=$(find "${dir}" -exec stat -c "%Y" \{\} \; \
| sort -n | tail -1)
sleep 10
done
echo "directory is now stable..."
AGGIORNAMENTO
un approccio ancora migliore sarebbe notificare attivamente al destinatario che un determinato file è stato trasmesso.
una soluzione molto semplice sarebbe copiare anche un file fittizio vuoto dopo che il payload è stato trasmesso. per esempio. per un file chiamato foo.avi
copia un altro file foo.avi.copyfinished
; quindi devi solo verificare l'esistenza di foo.avi.copyfinished
per vedere quel foo.avi
è pronto.
while true; do
for file_ready in *.copyfinished; do
file=${file_ready%.copyfinished}
if [ -e "${file}.converted" ]; then
echo "skipping already converted file ${file}" 1>&2
else
touch "${file}.converted"
do_convert "${file}"
fi
done
sleep 1
done
questa soluzione richiede ovviamente la collaborazione del mittente.
Correlati:arduino – Programmazione di più circuiti integrati utilizzando un singolo bus USBasp/SPI e Arduino IDE?