Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best practice for changing working directories inside scripts?

Tags:

bash

shell

zsh

perl

Do you think changing directories inside bash or Perl scripts is acceptable? Or should one avoid doing this at all costs?

What is the best practice for this issue?

like image 765
Tom Feiner Avatar asked Oct 27 '08 17:10

Tom Feiner


People also ask

How do I change the directory in a script?

To change directories, use the command cd followed by the name of the directory (e.g. cd downloads ). Then, you can print your current working directory again to check the new path.

How do I change the working directory in shell?

cd (change directory) The cd command used to change the current working directory in the Linux/Unix operating system. In the Windows operating system for the same purpose the cd or chdir command available. The cd command also available in the EFI shell (Extensible Firmware Shell).

What is working directory in shell script?

The shell always identifies a particular directory within which you are assumed to be working. This directory is known as the working directory (also known as the current working directory). To work with a file within your working directory, you need specify only the file name with a command.


2 Answers

Like Hugo said, you can't effect your parent process's cwd so there's no problem.

Where the question is more applicable is if you don't control the whole process, like in a subroutine or module. In those cases you want to exit the subroutine in the same directory as you entered, otherwise subtle action-at-a-distance creeps in which causes bugs.

You can to this by hand...

use Cwd;
sub foo {
    my $orig_cwd = cwd;
    chdir "some/dir";

    ...do some work...

    chdir $orig_cwd;
}

but that has problems. If the subroutine returns early or dies (and the exception is trapped) your code will still be in some/dir. Also, the chdirs might fail and you have to remember to check each use. Bleh.

Fortunately, there's a couple modules to make this easier. File::pushd is one, but I prefer File::chdir.

use File::chdir;
sub foo {
    local $CWD = 'some/dir';

    ...do some work...
}

File::chdir makes changing directories into assigning to $CWD. And you can localize $CWD so it will reset at the end of your scope, no matter what. It also automatically checks if the chdir succeeds and throws an exception otherwise. Sometimes it use it in scripts because it's just so convenient.

like image 103
Schwern Avatar answered Sep 28 '22 07:09

Schwern


The current working directory is local to the executing shell, so you can't affect the user unless he is "dotting" (running it in the current shell, as opposed to running it normally creating a new shell process) your script.

A very good way of doing this is to use subshells, which i often do in aliases.

alias build-product1='(cd $working-copy/delivery; mvn package;)'

The paranthesis will make sure that the command is executed from a sub-shell, and thus will not affect the working directory of my shell. Also it will not affect the last-working-directory, so cd -; works as expected.

like image 38
Hugo Avatar answered Sep 28 '22 09:09

Hugo