Mám následující skript, který kontroluje, zda je ve složce soubor a zda je soubor stabilní (toto je pro velký soubor videa, který přijímám).
#!/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
Jak upravit skript tak, aby mohl kontrolovat více souborů ve stejné složce a poté, co jsou všechny stabilní, spustit konverzní skript?
Přijatá odpověď:
ve vašem skriptu je řada problémů, počínaje:
folder1="path-to-folder"
cd $folder1
while file=$(ls "$folder1") ...
to opravdu dělá cd path-to-folder; ls path-to-folder
; if path-to-folder
je absolutní (začínající '/' jako ve vašem příkladu), může to fungovat, ale nebude to fungovat, kdykoli použijete relativní cesty.
nebude to fungovat ani v případě, že path-to-folder
obsahuje mezery, protože byste měli všude používat uvozovky, např. cd "$folder1"
pak uděláte while file=$(ls ...)
udělá nekonečnou smyčku jako file
bude vždy nastaveno na něco (obsah adresáře).
správná syntaxe by byla for file in $(ls ...)
, který přestane fungovat, jakmile budete mít názvy souborů s mezerami (protože smyčka poběží na foo
a bar
pokud máte soubor s názvem foo bar
). zkontrolujte, proč byste nikdy neměli analyzovat výstup ls. místo použití ls
můžete jednoduše udělat for file in *
.
konečně můžete mít soubory, které se mění, i když se jejich velikost již nemění.
dobrý způsob, jak iterovat přes soubory, je find
příkaz; dobrý způsob, jak zkontrolovat, zda se něco nezměnilo, je mtime
souboru.
následující funkce vám poskytne hodnotu pro poslední úpravu (mtime) libovolného souboru v daném adresáři
folder1="/path-to-folder"
find "${folder1}" -exec stat -c "%Y" \{\} \; \
| sort -n | tail -1
takže váš skript může vypadat takto:
#!/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..."
AKTUALIZACE
ještě lepším přístupem by bylo aktivně upozornit příjemce, že daný soubor byl přenesen.
Velmi jednoduchým řešením by bylo také zkopírovat prázdný fiktivní soubor po přenesení užitečného zatížení. např. pro soubor s názvem foo.avi
zkopírujte jiný soubor foo.avi.copyfinished
; takže stačí zkontrolovat existenci foo.avi.copyfinished
abyste viděli, že foo.avi
je připraven.
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
toto řešení samozřejmě vyžaduje spolupráci odesílající strany.
Související:arduino – Programování více integrovaných obvodů pomocí jediné sběrnice USBasp/SPI a Arduino IDE?