in reply to Re^2: search and replace with a variable
in thread search and replace with a variable

Your CGI application probably runs as some other user and group id's (not your userid). The user is dependent on the web server configuration -- possibly "nobody", or "www-...". Does the user or group that the webserver runs as have permission to write to files?

More importantly, the code you posted won't compile because it uses strict, but never declares $fqdn1, which is the variable your substitution operator is interpolating as the substitute. You should be seeing "Global symbol "$fqdn1" requires explicit package name at XXXXXX.cgi line ...". That may show up in your server log. The server log may have other helpful information, but at minimum, the code you posted will produce that error. If the code you posted is different from the code you're running, go give yourself 30 lashes, repent, and don't do it again.

My guess is that your actual script just doesn't have "use strict" at the top, and you added it here so we wouldn't jump on you. Because the bug you're describing, the fact that the substitution isn't replacing the match with anything, is exactly what would happen if you try to substitute $fqdn1 (which is undeclared and undefined), instead of $fqdn, which holds a parameter value. That means we're being lied to when you say "Here's the entire code." If that were the entire code, and the exact code, you would have a different set of symptoms from what you reported.

Furthermore, the code you posted could be refined a bit, and still needs to implement flocking so that you avoid race conditions that can occur when two web hits come in within close time proximity to each other. Here is an untested example:

use strict; use warnings; use CGI; use Getopt::Long; use FindBin; use Fcntl q(:flock); use constant FILENAME => "FindBin::Bin/file.csv"; open my $self_fh, "< $0" or die "Cannot open self: $!"; flock $self_fh, LOCK_EX or die "Cannot obtain an exclusive lock: $!"; open my $infh, '<', FILENAME or die "Unable to open input file: $!"; open my $outfh, '>', FILENAME . '.out' or die "Unable to open output f +ile: $!"; my $q = CGI->new; chomp ( my $fqdn = $q->param('fqdn') ); chomp ( my $address = $q->param('address') ); while( <$infh> ) { s/RECORDNAME/$fqdn/; s/RECORDIP/$address/; print $outfh $_; } close $infh; close $outfh or die "Failed to close output file: $!"; rename FILENAME . '.out', FILENAME or die "Unable to replace original file: $!"; close $self_fh or die $!; # Releases the lock. print "Content-type: text/plain\n\n"; print "$address / $fqdn";

The type of locking here is "blocking". In your finished product you might instead want to use a non-blocking flock, and if a lock wasn't obtained, sleep for one second and try again. Repeat five times, and if still unsuccessful, report a useful error message and exit.


Dave