My complete perl script is
chdir ("/etc" or die "cannot change: $!\n");
print "\nCurrent Directory is $ENV{PWD} \n";
and I am getting output (not as expected)
bash-3.2$ perl test.pl
Current Directory is /home
P.S. /home
is where I am executing the test.pl
You can use chdir function in Perl to change a directory and go to a new location. You will need to have the required permission to change a directory and go inside the new directory.
Use chdir. If both a drive and a directory is provided, both the current drive and the current directory on that drive will be changed. This differs from the cd shell command which only does the latter. Both slashes (\ and /) can be used as a separator and to prefix a UNC path.
getcwd and friends my $cwd = getcwd(); Returns the current working directory.
The make_path function creates the given directories if they don't exist before, much like the Unix command mkdir -p . The function accepts a list of directories to be created.
You should move or die
outside of chdir(...)
, i.e.:
chdir("/etc") or die "cannot change: $!\n";
With what you have currently, the expression "/etc" or die "cannot change: $!\n"
is evaluated first.
Its result is "/etc"
and die()
never gets executed. or die()
should be "applied to" chdir()
call, not to its argument.
Do print(cwd);
to print current working directory. Don't forget to use Cwd;
use Cwd;
chdir("/etc") or die "cannot change: $!\n";
print(cwd);
Alex Shesterov has given the right answer, but since this has some interesting details, I will elaborate. Here is the documentation for or
:
Binary "or" returns the logical disjunction of the two surrounding expressions. It's equivalent to || except for the very low precedence. This makes it useful for control flow:
print FH $data or die "Can't write to FH: $!";
This means that it short-circuits: the right expression is evaluated only if the left expression is false.
What the Perl documentation writer meant by "This means that", I guess we'll never know, but the following part of the sentence is important: It short-circuits.
In Perl, "true" and "false" are handled somewhat conveniently, in that there are only a few false values, and all other values are considered true. For example, undef
, 0
, the empty string and the empty list are examples of "false" values. And a string such as the one in this question "/etc"
can never be false.
When passing arguments to a function/subroutine, lists are used. A list is a series of independent statements, such as:
"foo", "bar", "baz" # three strings, foo bar baz
qw(foo bar baz) # same thing
my @array = qw(foo bar baz);
@array; # same thing, unless scalar context
However, the or
operator does not create a list, rather it forces the statement to be evaluated right away, before it is passed to the function. So, this is what happens:
chdir ("/etc" or die "cannot change: $!\n");
# ^^^^^^-- true value
--> "/etc" or die ? --> "/etc"
chdir("/etc");
You have found a new version of this classic mistake. Usually this is what people do:
open my $fh, "<", "file" || die "Cannot open: $!";
Which is the same mistake, in a more subtle version: The logical or ||
operator has higher precedence than the comma operator, which makes the above statement similar to:
open my $fh, "<", ( "file" || die "Cannot open: $!" );
Which is exactly the problem you ran into: The die
statement can never logically be executed, since a string with a file name can never (unless it is empty, or zero) be false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With