Wednesday, August 26, 2009

Are We There, Yet? Using fuser() to See If The Job's Done.

Ever write a script that ends before the things in it should?

The symptom is a file that gets partially written or partially copied. Sometimes the output files are zero-length. One example is the batch-mode sftp I wrote about last post.

Here's an illustrative example, followed by a trick to solve it.

In the empty-sftp program, empty spawns an sftp session, which runs in parallel, waiting for me (really empty, but it thinks it's me) to type ftp commands. If I only want to run one command


sftp> get filename

I can exit my script after issuing the command, but the pty will still be running. I can kill the pty before I exit the script, but if the file transfer hasn't finished, the kill will truncate the output.

The basic problem is that there is no process that I can watch that terminates after the file transfer ends; like any shell (which is really what it is), sftp just keeps running, waiting for the next command.

The trick:

When the transfer's over, sftp closes the output file. We can watch to see when that happens, like this:
while true
do
sleep 1
/sbin/fuser $localfile || break

done

As soon as it finishes, we kill the sftp session, and exit.



No comments: