Reputation: 1757
I just started learning Perl and i'm having a problem related to opening a file that is in the same directory as my program.
#!/usr/bin/perl -w
$proteinfilename = 'NM_021964fragment.pep';
open(PROTEINFILE, $proteinfilename) or die "Can't write to file '$proteinfilename' [$!]\n";
$protein = <PROTEINFILE>;
close(PROTEINFILE);
print "Essa é a sequência da proteína:\n";
print $protein, "\n";
exit;
When I specify the directory of the file, changing from 'NM_021964fragment.pep' to '/Users/me/Desktop/programa/NM_021964fragment.pep', the program works. But shouln't it work even without me specifying the directory, as the program and the file are in the same folder?
Upvotes: 4
Views: 698
Reputation: 385496
Relative paths are relative to the current work directory, not the script's directory. When the script worked, they happened to be the same. But as you found, that's not always the case. You could use the following to achieve the behaviour you describe:
use Cwd qw( realpath );
use Path::Class qw( file );
my $script_dir = file(realpath($0))->dir;
my $input_file = $script_dir->file('NM_021964fragment.pep');
Upvotes: 1
Reputation: 67900
If you are doing a simple file read, you can use the <>
diamond operator for simplicity.
use strict;
use warnings;
my $protein = <>;
print "Essa é a sequência da proteína:\n";
print "$protein\n";
And use the script like so:
perl script.pl NM_021964fragment.pep
This will force you to use the correct paths, assuming you use tab autocomplete when you run your script.
Using a command-line argument this way is somewhat unsafe, since it is possible to execute arbitrary code through unprotected open
commands. You can use the module ARGV::readonly
to prevent such things. Or simply use the code itself, it is rather simple:
for (@ARGV){
s/^(\s+)/.\/$1/; # leading whitespace preserved
s/^/< /; # force open for input
$_.=qq/\0/; # trailing whitespace preserved & pipes forbidden
};
Upvotes: 2