Ugyan megoldottam a gondomat, de érdekel az, hogy miért nem működött egy korábbi script változatom. A picike scriptem annyit csinál, hogy ssh-n keresztül felmásol a router-em RAM-jába file-okat. Az rsync nem jó, mert nincs elég hely ahhoz, hogy a router-re feltegyem az rsync-et. A lényeg, hogy szimbolikus linket is kell másolni. A program rekurzívan bejárja az alkönyvtárakat. Ez a változat működik:
#!/bin/bash
BASE='/tmp'
copy() {
unset list
i=0
while read -r; do
list[i++]="$REPLY"
done < <(ls -1)
lenlist=$i
i=0
while [ $i -lt $lenlist ]; do
file="${list[i++]}"
len=${#file}
if cd "$file" &>/dev/null; then
ssh locsemege@router "
cd \"$BASE/$dir\"
mkdir \"$file\"
"
dir+="/$file"
(copy)
dir="${dir%/*}"
cd ..
continue
fi
if [ -h "$file" ]; then
ssh locsemege@router "
cd \"$BASE/$dir\"
ln -s \"`readlink $file`\" \"$file\"
"
continue
fi
if [ "${file:len-1}" != '~' ]; then
scp -C "$file" locsemege@router:"$BASE/$dir/$file"
fi
done
}
ssh locsemege@router 'rm -Rf /tmp/www; mkdir /tmp/www'
dir='www'
cd /home/locsemege/router/www
copy
A gondom az, hogy amennyiben nem másoltam az aktuális file listát egy tömbbe, hanem akár pipe-oltam
ls -1 | while read -r; do
...
done
akár process helyettesítést használtam
while read -r; do
...
done < <(ls -1)
akár a file listát irányítottam a ciklusba
list="`ls -1`"
while read -r; do
...
done <<<"$list"
az történt, hogy amikor a legmélyebb ciklusból visszatért a copy függvény, az őt hívó ciklusból is azonnal kilépett. Debugoltam, az utóbbi esetben a file lista nem sérült, a visszatérés után megvolt. Pedig a rekurzív hívást gömbölyded zárójelbe írva subshellben teszem: (copy). A változók ennek megfelelően nem is íródnak felül, a jelenlegi programverzió működik.
Az a gyanúm, az átírányításkor lehet valami olyasmi, hogy a rekurzión belül a file descriptorok esetében nincs mentés, vagy nem tudom, lényeg, hogy ha a belső read visszatér EOF-fal, a külső, hívó ciklus is azonnal visszatér, tehát hiába vannak még a listának feldolgozatlan elemei a read EOF-fal tér vissza. Pedig nem szeretném. Azt nem mondom, hogy nem kéne, mert nyilván én nem tudok valamit.
Az utolsó feltételben azért vizsgálom a filenév utolsó karaktereként a tilde jelet, mert az editor által létrehozott backup file-okat nem szeretném a router-re másolni.
Miért nem működtek a triviális programváltozataim, miért kellett egy tömbből feldolgoznom a listaelemeket rekurzív hívás esetén, miért nem működött az átirányítás?
Megoldás.