4

According to the manual, chdir, Changes the working directory to EXPR, if possible.

This script, when executed from cmd.exe:

my $path = 'C:\\some\\path\\';
print "$path\n";
chdir("$path") or die "fail $!";

results in this output:

C:\some\path\

but when I am returned to the command prompt - I'm still at the original directory. Am I misunderstanding the purpose of chdir?

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
dls
  • 4,146
  • 2
  • 24
  • 26

3 Answers3

7

See the FAQ I {changed directory, modified my environment} in a perl script. How come the change disappeared when I exited the script? How do I get my changes to be visible?

In the strictest sense, it can't be done—the script executes as a different process from the shell it was started from. Changes to a process are not reflected in its parent—only in any children created after the change.

The same answer applies to Windows as well.

You can modify the starting directory of subsequent cmd.exe invocations, or of child processes by messing with shortcuts and/or the registry.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
6

When a shell runs a program, it essentially forks then execs the program -- in this case, your perl script. The directory within that forked process has been changed, and then that process dies. You're then returned to the original shell process.

Conspicuous Compiler
  • 6,403
  • 1
  • 40
  • 52
  • yup - that would make sense. could I spawn another cmd.exe instance starting it at the appropriate directory? – dls Mar 08 '10 at 22:29
  • Erm, no such thing as `fork` on Windows. It's just that the directory the Perl script is using is not the one that the shell uses. – Joey Mar 09 '10 at 00:15
  • 1
    Sure there's fork() on Windows. Cygin emulates it quite completely: http://stackoverflow.com/questions/985281/what-is-the-closest-thing-windows-has-to-fork But, you'll note I used the words "essentially forks". It probably is using CreateProcess ( http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx ) on the backend at some point. – Conspicuous Compiler Mar 09 '10 at 00:41
  • @dls: You can always just execut cmd from your perl script with system('cmd') That'll start up a command shell in the desired directory. That call to system will return when somebody types 'exit' to exit the cmd shell. – Conspicuous Compiler Mar 09 '10 at 00:53
  • 1
    this accomplishes what I'm after: system("cmd /K cd /d $final_dest"); where $final_dest is the desired path.. thanks! – dls Mar 09 '10 at 19:50
1

I have changing directories and command environments by using the perl -x switch to execute Perl code in embedded in a file.

@rem = '--*-Perl-*--'
@echo off
set TMPBAT=%TMP%\%0_temp.bat
perl -x -S %0 %*
if %errorlevel% == 2000 goto cleanup
goto endofperl
#!perl
#line 9

use strict;
use warnings; 
use BatchTool;


__END__
:endofperl
if exist %TMPBAT% call %TMPBAT%
:cleanup
set TMPBAT=

BatchTool is a module that writes DOS commands to $ENV{TMPBAT} if 1) it doesn't exist or 2) is older than the source script.

Axeman
  • 29,660
  • 2
  • 47
  • 102