Я согласен, что это ошибка в реализации findloc () в Intel Fortran. Я создал отчет об ошибках Intel для наших разработчиков.
Текущий рабочий каталог локален для выполняющейся оболочки, таким образом, Вы не можете влиять на пользователя, если он не "отмечает точкой" (выполнение его в текущей оболочке, в противоположность выполнению его обычно создание нового процесса оболочки) Ваш сценарий.
Очень хороший способ сделать это состоит в том, чтобы использовать подоболочки, которые я часто делаю в псевдонимах.
alias build-product1='(cd $working-copy/delivery; mvn package;)'
Круглая скобка удостоверится, что команда выполняется от подоболочки и таким образом не будет влиять на рабочий каталог моей оболочки. Также это не будет влиять на последний рабочий каталог, таким образом, CD-; работы как ожидалось.
Как сказанный Hugo, Вы не можете произвести cwd своего родительского процесса, таким образом, нет никакой проблемы.
То, где вопрос более применим, - то, если Вы не управляете целым процессом, как в подпрограмме или модуле. В тех случаях Вы хотите выйти из подпрограммы в том же каталоге, как Вы вошли, в других отношениях тонкий action-at-a-distance закрадывается который ошибки причин.
Вы можете к этому вручную...
use Cwd;
sub foo {
my $orig_cwd = cwd;
chdir "some/dir";
...do some work...
chdir $orig_cwd;
}
но это имеет проблемы. Если подпрограмма возвратится рано или умрет (и исключение захватывается), то Ваш код все еще будет в some/dir
. Кроме того, chdir
s мог бы перестать работать, и необходимо не забыть проверять каждое использование. Bleh.
К счастью, существует пара модулей для создания этого легче. File::pushd один, но я предпочитаю File::chdir.
use File::chdir;
sub foo {
local $CWD = 'some/dir';
...do some work...
}
File::chdir превращает изменяющиеся каталоги в присвоение $CWD
. И можно локализовать $CWD
таким образом, это сбросит в конце Вашего объема, несмотря ни на что. Это также автоматически проверяет если chdir
следует и выдает исключение иначе. Иногда это использует его в сценариях, потому что это настолько удобно.
Я часто не делаю этого, но иногда это может сохранить довольно мало головной боли. Просто убедитесь, что при изменении каталогов Вы всегда возвращаетесь к каталогу, с которого Вы запустили. Иначе изменение путей выполнения кода могло оставить приложение где-нибудь, это не должно быть.
Я буду комментарии второго Schwern и Hugo выше. Отметьте осторожность Schwern в отношении возврата исходному каталогу в случае неожиданного выхода. Он предоставил соответствующий код Perl для обработки этого. Я укажу на оболочку (Bash, Korn, Граница) команда прерывания.
захватите "$saved_dir CD" 0
возвратится к saved_dir на выходе подоболочки (если Вы будете.'ing файл).
микрофон
Для Perl у Вас есть модуль File::pushd от CPAN, который делает локально изменение рабочего каталога довольно изящным. Заключение в кавычки резюме:
use File::pushd;
chdir $ENV{HOME};
# change directory again for a limited scope
{
my $dir = pushd( '/tmp' );
# working directory changed to /tmp
}
# working directory has reverted to $ENV{HOME}
# tempd() is equivalent to pushd( File::Temp::tempdir )
{
my $dir = tempd();
}
# object stringifies naturally as an absolute path
{
my $dir = pushd( '/tmp' );
my $filename = File::Spec->catfile( $dir, "somefile.txt" );
# gives /tmp/somefile.txt
}
Полагайте также, что Unix и Windows имеют созданный в стопке каталога: pushd и popd. Это чрезвычайно просто в использовании.
Вообще выполнимо пытаться использовать полностью определенные количественно пути и не сделать какие-либо предположения, на котором каталоге Вы в настоящее время находитесь в? например.
use FileHandle;
use FindBin qw($Bin);
# ...
my $file = new FileHandle("< $Bin/somefile");
вместо
use FileHandle;
# ...
my $file = new FileHandle("< somefile");
Это, вероятно, будет легче в конечном счете, поскольку Вы не должны волноваться о странных вещах, происходящих (Ваша смерть сценария или быть уничтоженным, прежде чем она могла отложить текущий рабочий каталог туда, где это было), и является вполне возможно более портативным.