Write data to a file using CGI-perl - perl

I have a problem in writing data to a file using CGI. the code is as follows:
#!/usr/bin/perl
use strict;
use warnings;
use CGI ":standard";
print "Content-type:text/html \n\n";
open (FILE, '>', "file.txt") or die ("Could not open the file for writing...$!");
print FILE "something";
close(FILE);
The above code is giving the following error:
"Could not open the file for writing...Permission denied at /var/www/cgi-bin/wfile.cgi line 8.
The read and write permission for the file is already set... Please help!!!

The perl script will run as the user that apache/httpd/whatever is running as. You need to make sure that the directory and file is writeable by that user. Why not try writing to /tmp/ first.

Related

Reading a file in perl with CGI?

The code is supposed to read a file in perl but is supposed to be modified with CGI. I have looked over several tutorials, and think it is the file path, but cannot get it to work. Any ideas? I'm newer to CGI and perl. Trying to run it through html.
#!/usr/bin/perl
use warnings;
use strict;
my $filename = '/home/cisstudent/test.txt';
open(FH, '<', $filename) or die $!;
print("File $filename opened successfully!\n");
close(FH);
The first line of your posted code is incorrect - it should be #!/usr/bin/perl - /usr, not /user.
If that doesn't fix the script (or if it's just a typo in the post, rather than in your actual code), then you'll need to provide additional details, such as how you're running the script and the error message received when you attempt to run it.

Irregular Behavior with Perl print

I'm attempting to print out to two different files. For some reason, print statements work fine for one file, but not for the other. When I run this program, filter2.out consists of a single line that reads "Beginning". filter2.err remains empty.
open(OUTPUT, "> Filter2/filter2.out");
open(ERROR, "> Filter2/filter2.err");
print OUTPUT "Beginning\n";
print ERROR "Beginning\n";
UPDATE: So I was running this at the beginning of a larger program and realized that it only updates the ERROR file in batches or when the file is closed. Any idea why this occurs?
Consider adding
use strict;
use warnings;
to the top of your script. These statements will help catch errors that are otherwise silently ignored by Perl. In addition, consider adding error checking to your open calls: in all likelihood, it's not actually opening. I'd write it like this:
use strict;
use warnings;
open(OUTPUT, "> Filter2/filter2.out")
or die "Can't open filter2.out: $!";
open(ERROR, "> Filter2/filter2.err")
or die "Can't open filter2.err: $!";
print OUTPUT "Beginning\n";
print ERROR "Beginning\n";
for example, by just adding adding strict and warnings I got:
print() on closed filehandle OUTPUT at .\printer.pl line 6.
print() on closed filehandle ERROR at .\printer.pl line 7.
Hmm...!
By adding error checking, I got:
PS C:\dev> perl .\printer.pl
Can't open filter2.out: No such file or directory at .\printer.pl line 4.
Aah! Looking, I didn't have the folder. After I added the folder, everything ran fine. You'll probably find something similar.
Finally, you should probably also use the modern, lexical file handles. This helps catch other errors (like re-used handle names.) Thus, the final script would look like:
use strict;
use warnings;
open(my $output, ">", "Filter2/filter2.out")
or die "Can't open filter2.out: $!";
open(my $error, ">", "Filter2/filter2.err")
or die "Can't open filter2.err: $!";
print $output "Beginning\n";
print $error "Beginning\n";
Viola! Now you can see exactly where the problem fails, as it fails, and make sure that other libraries or code you write later can't accidentally interfere with your file handles.
You need to check that your files were properly opened. Also it's better to use local variables as file handles instead of bare words:
open( my $err, "> Filter2/filter2.err") or die "Couldn't open error: $!"
print $err "Beginning\n"

perl unable to copy contents of file and print it

I need to read/copy the contents of a file(test.pl) just as the way it is formatted and email it.
I am using the following code but I am unable to print anything out.
I get this error even though the file exists in the same directory.
Failed: No such file or directory
Code:
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
open my $fh, '<', 'test.pl '
or die "Failed: $!\n";
my $text = do {
local $/;
<$fh>
};
close $fh
or die "Failed again: $!\n";
print $text, "\n";
It looks like there is an extra space in the filename you are trying to open. In your open statement, try changing 'test.pl ' to 'test.pl'.
if you are going to read files names from STDIN (user's input), you may want to trim them either by using regex (s/^\s+//....) or Text::Trim among other validations.

Error when running a DOS command in CGI

I tried to run a simple copy of one file to another folder using Perl
system("copy template.html tmp/$id/index.html");
but I got the error error: The syntax of the command is incorrect.
When I change it to
system("copy template.html tmp\\$id\\index.html");
The system copies another file to the tmp\$id foler
Can someone help me?
I suggest you use File::Copy, which comes with your Perl distribution.
use strict; use warnings;
use File::Copy;
print copy('template.html', "tmp/$id/index.html");
You do not need to worry about the slashes or backslashes on Windows because the module will take care of that for you.
Note that you have to set relative paths from your current working directory, so both template.html as well as the dir tmp/$id/ needs to be there. If you want to create the folders on the fly, take a look at File::Path.
Update: Reply to comment below.
You can use this program to create your folders and copy the files with in-place substitution of the IDs.
use strict; use warnings;
use File::Path qw(make_path);
my $id = 1; # edit ID here
# Create output folder
make_path("tmp/$id");
# Open the template for reading and the new file for writing
open $fh_in, '<', 'template.html' or die $!;
open $fh_out, '>', "tmp\\$id\index.html" or die $!;
# Read the template
while (<$fh_in>) {
s/ID/$id/g; # replace all instances of ID with $id
print $fh_out $_; # print to new file
}
# Close both files
close $fh_out;
close $fh_in;

Unable to understand reason for Tie::File failure

I have the following code
#!/usr/bin/perl
use Tie::File;
tie my #last_id, 'Tie::File', 'last_id.txt' or die "Unable to open this file !$i";
print #last_id[0];
exit;
and a file named last_id.txt with something like this in it
1
2
3
4
5
6
When I run the program nothing gets output. I tried $last_id[0] but still nothing. :/
I have latest ActivePerl installed.
EDIT:
Now I get the Unable to open this file message, but the file exists in the same directory as the program source file.
As you say, #last_id[0] is wrong and should be $last_id[0]. But this won't cause the problem you are seeing.
Note that the program won't look for last_id.txt in the same directory as the Perl source file unless it it also the current working directory.
You should first of all change the error variable used in the tie line to $! like this
tie my #last_id, 'Tie::File', 'last_id.txt'
or die "Unable to open this file: $!";
as the variable $i contains nothing useful. This will tell you the reason for the failure of tie, which may be something other than no such file or directory.
You should also use strict and use warnings at the start of your program, as this will flag simple errors that are easy to overlook.
Finally, try fully-qualifying the filename by adding an absolute path to it. That will get around the problem of the program looking in the wrong directory by default.
Update
If the problem is that you have no write access to the file then you can fix it by opening it read-only.
You need the Fcntl module to define the O_RDONLY constant, so put this at the top of your program
use Fcntl 'O_RDONLY';
then the tie statement goes like this
tie my #last_id, 'Tie::File', 'last_id.txt', mode => O_RDONLY
or die "Unable to open this file: $!";
The problem should go away if you use absolute paths
BEGIN {
use File::Spec;
use File::Basename qw' dirname ';
use vars qw' $thisfile $thisdir ';
$thisfile = File::Spec->rel2abs(__FILE__);
$thisdir = dirname($thisfile);
}
...
tie ... "$thisdir/last_id.txt"