¿Cómo podríamos saber si un fichero que está siendo subido por FTP ha acabado o no de subirse? Hay algunas posibles soluciones en esta conversación de SuperUser.com, la última de las cuales, es la que he usado.
Para los testeos, he usado un servidor vsFTPd (configurado tal y como expliqué aquí) sobre un servidor CentOS 5.4. Como no tenía ficheros grandes para hacer el test, he creado uno de forma instantánea, con el siguiente comando:
[root@adripc]# fallocate -l 100M test.img
[root@adripc]# ls -lah test.img
-rw-r–r– 1 root root 100M Jul 18 10:20 test.img
La idea es usar lsof para saber el PID del proceso de vsFTPd que está siendo usado para subir el fichero destino, y entoces monitorizar ese PID. El problema que me he encontrado, al menos con el entorno de test que he usado, es que ese PID de subida puede cambiar durante la subida. No sé bien bien porqué razón, pero en mi caso cambia. Si cambia el PID entonces ya no podremos monitorizar ese PID, ya que el PID habrá finalizado (o no) pero no así la subida, que estará usando otro PID diferente.
En este caso, la solución es más sencilla aun, ya que bastará con símplemente ir consultando mediante lsof y en caso de devolver vacío, nos indicará que no hay ningún proceso usando el fichero y que por tanto, la subida ha finalizado. Así, nos dará igual que el PID cambie. Lo único importante es que durante la subida del fichero, ese archivo tendrá un PID asociado, mientras que cuando haya acabado el upload, no tendrá ningún PID y por tanto lsof devolverá vacío.
Así pues, un script que pondríamos en un cron periódico para monitorizar subidas, podría ser el siguiente:
#!/bin/bash
username='userftp'
source='/home/userftp/'
files=`ls $source`
for file in $files
do
echo "Trabajando con... $file"
## CHECK FOR PID
allsource=$source$file
echo "... ALLSOURCE: $allsource"
pid=`/usr/sbin/lsof -t $allsource`
echo "... PID: $pid"
## UPLOAD FINISHED if no PID is found
if [ -z $pid ]; then
## Upload acabado. Aquí pondrías el código que necesites.
fi
done
Lo que haría el script es mirar todos los ficheros no ocultos de un directorio de subida ($source), e identificaría aquellos que ya han acabado de subirse. ¿Para qué sirve ésto? Buena pregunta. Quizá te interese cambiar los permisos una vez subido, o mover el fichero subido a otro servidor, o a otro directorio, o enviar un mai de avisol. Hay muchas posibilidades.
Si llamas a este script, por ejemplo, checkupload.sh, podrás montar un cron para monitorizar subidas, por ejemplo, cada 5 minutos:
[root@MyServer]# crontab -e
*/5 * * * * /data/scripts/checkupload.sh
Ahora ya tendrás controladas las subidas FTP para tus usuarios, pero cuidado, éste script no monitoriza que efectivamente se traten de subidas FTP. Si el propio usuario no está bien configurado y tiene acceso al shell, podría crear ficheros manualmente en su directorio de subidas ftp (la home en el ejemplo) y el script también los trataría. Incluso trabajando como root, podríamos por error mover o copiar algún fichero a ese directorio, y también se trataría. Así pues, mejor tener claro que los directorios para usuarios FTP, son únicamente para eso, para FTP.
Foto por johntrainor