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?