locked_user satishkambam has asked for the wisdom of the Perl Monks concerning the following question:

I was wondering if there's a way to wait for a file to be updated, and then read from it once it's updated. So if I have file.txt, I want to wait until something new is written to it, and then read it/process it/etc in UNIX Right now iam using Win32::FileSystem::Watcher; for windows ..

Replies are listed 'Best First'.
Re: wait until something new is written to it
by moritz (Cardinal) on Nov 09, 2011 at 13:55 UTC
Re: wait until something new is written to it
by roboticus (Chancellor) on Nov 09, 2011 at 13:57 UTC
Re: wait until something new is written to it
by zentara (Cardinal) on Nov 09, 2011 at 16:44 UTC
    So if I have file.txt, I want to wait until something new is written to it, and then read it/process it/etc in UNIX

    This suggestion of the use of select, is only if you have control over what writes to your files. Otherwise be more specific in your problem description, like adding a code example.

    To do what Win32::FileSystem::Watcher does in Windows, on linux, you can use a IO::Select method or what is commonly called file events in a bunch of modules. It is slightly different than an IO::Notify type of watcher, because you actually control and watch the writing to the filehandle, rather than just react to bytes size change or some other file system access controls.

    The old way, coming down straight from C, is to use select. Perl has a select statement, see perldoc -f select, or better use the IO::Select module. For instance see file read timeout or Google for "perl io::select". Normally you will see IO::Select used to watch a few handles simultaneously, but you can have select watch just one file.... firing off a subroutine everytime something is available to be read. Here is a simple example of how it would be used on Linux.

    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; my $pid = open3(\*WRITE, \*READ,\*ERROR,"/bin/bash"); my $sel = new IO::Select(); $sel->add(\*READ); $sel->add(\*ERROR); my($error,$answer)=('',''); while(1){ print "Enter command\n"; chomp(my $query = <STDIN>); #send query to bash print WRITE "$query\n"; foreach my $h ($sel->can_read) { my $buf = ''; if ($h eq \*ERROR) { sysread(ERROR,$buf,4096); if($buf){print "ERROR-> $buf\n"} } else { sysread(READ,$buf,4096); if($buf){print "$query = $buf\n"} } } } waitpid($pid, 1); # It is important to waitpid on your child process, # otherwise zombies could be created.

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh