Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I want to change directories during the use of an open3 call, but only for that call. Ideally I would like to change the directory that the shell starts up in and not affect the calling perl script at all. So far this is my best go at what I want, but this solution doesn't strike me as the best:
#!/usr/bin/perl -w use strict; use Cwd; my $new_dir = "/usr/bin"; my $dir; my $original_dir = getcwd; print "$original_dir\n"; chdir($new_dir); $dir = getcwd; print "$dir\n"; chdir($original_dir); $dir = getcwd; print "$dir\n";

Replies are listed 'Best First'.
Re: Best way to change directories for a script?
by Util (Priest) on Aug 22, 2005 at 05:10 UTC

    As long as you are not using threads, I see nothing non-optimal in your solution.

    My sleepy mind just inverted the solution; use a wrapper that just does chdir and exec the command.
    Untested code:

    my $new_dir = "/usr/bin"; my $wrapper = 'perl -we chdir(shift)and(exec@ARGV)'; my($wtr, $rdr, $err); my $pid = open3( $wtr, $rdr, $err, "$wrapper $new_dir some cmd and args", );
    Kludgey. I like your current method better.

Re: Best way to change directories for a script?
by tilly (Archbishop) on Aug 22, 2005 at 06:44 UTC
    There are multiple solutions to this. The absolute safest is to launch the command:
    "perl", "-e", qq{chdir "/usr/bin"; exec @ARGV;}, $original_cmd, @args
    Another cute one is to use my ReleaseAction. The following example is straight from the documentation:
    use Carp; use Cwd; use ReleaseAction; sub cd_to { chdir($_[0]) or confess("Cannot chdir to $_[0]: $!"); } sub tmp_cd { my $cwd = cwd(); cd_to(shift); ReleaseAction->new(\&cd_to, $cwd); } sub something_interesting { my $in_dir = tmp_cd("some_dir"); # Do something interesting in the new dir # I will automagically return to the old dir # when I exit the subroutine and $in_dir goes # out of scope. }
    Note that this is less safe than the previous solution because if someone renames or deletes your previous working dir, when you try to cd back you will fail (or worse yet will succeed in going to the wrong place). However that risk is miniscule, and when I had to write lots of batch jobs, it was a risk that I was generally willing to accept.
Re: Best way to change directories for a script?
by xdg (Monsignor) on Aug 22, 2005 at 10:51 UTC

    With the caveat that I haven't used it, I did stumble across File::chdir recently, which supposedly lets you localize $CWD to change directories and the change is reverted as soon as the localization goes out of scope. Seemed handy as a way of letting something else keep track of the old directory instead of doing it yourself.

    Again, unlikely it's thread safe -- almost no directory change is, I believe -- you just have to use absolute paths for everything if you're using threads (or fork on Windows).

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.