Измените рабочий каталог в моем текущем контексте оболочки при запуске Node script
Я пытаюсь изменить рабочий каталог моего Node.js script, когда он запускается из bin script. У меня есть что-то вроде следующего:
#!/usr/bin/env node
process.chdir('/Users')
Когда я запускаю этот файл с ./bin/nodefile
, он завершается, но рабочий каталог текущего контекста оболочки не изменился. Я также пробовал shelljs, но это тоже не работает.
Каков наилучший способ сделать это? Я понимаю, что это работает, но это просто в отдельном процессе.
Ответы
Ответ 1
Правильный способ изменения каталогов на самом деле с process.chdir(directory)
. Вот пример из документации:
console.log('Starting directory: ' + process.cwd());
try {
process.chdir('/tmp');
console.log('New directory: ' + process.cwd());
}
catch (err) {
console.log('chdir: ' + err);
}
Это также можно проверить в Node.js REPL:
[[email protected] ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'
Ответ 2
Нет встроенного метода для Node для изменения CWD базовой оболочки, запускающей процесс Node.
Вы можете изменить текущий рабочий каталог процесса Node с помощью команды process.chdir()
.
var process = require('process');
process.chdir('../');
Когда процесс Node существует, вы вернетесь в CWD, в котором вы запустили процесс.
Ответ 3
То, что вы пытаетесь сделать, невозможно. Причина этого в том, что в системе POSIX (Linux, OSX и т.д.) Дочерний процесс не может изменять среду родительского процесса. Это включает в себя изменение родительского рабочего процесса и переменных среды.
Когда вы находитесь в командной строке, и вы идете выполнить свой Node script, ваш текущий процесс (bash
, zsh
, что угодно) порождает новый процесс, который имеет свою собственную среду, обычно копию текущую среду (это можно изменить с помощью системных вызовов, но это выходит за рамки этого ответа), позволяя этому процессу делать все, что ему нужно, в полной изоляции. Когда выйдет подпроцесс, управление возвращается в ваш процесс оболочки, где среда не была затронута.
Есть много причин для этого, но для одного представьте, что вы выполнили script в фоновом режиме (через ./foo.js &
), и по мере его запуска он начал изменять рабочий каталог или переопределять ваш PATH
, Это был бы кошмар.
Если вам нужно выполнить некоторые действия, требующие изменения рабочего каталога вашей оболочки, вам нужно написать функцию в своей оболочке. Например, если вы используете Bash, вы можете поместить это в свой ~/.bash_profile
:
do_cool_thing() {
cd "/Users"
echo "Hey, I'm in $PWD"
}
и тогда эта классная вещь выполнима:
$ pwd
/Users/spike
$ do_cool_thing
Hey, I'm in /Users
$ pwd
/Users
Если вам нужно делать более сложные вещи, вы всегда можете вызывать ваш nodejs script из этой функции.
Это единственный способ выполнить то, что вы пытаетесь сделать.
Ответ 4
Короткий ответ: нет (легко?), но вы можете сделать что-то, что служит вашей цели.
Я сделал аналогичный инструмент (небольшая команда, которая, учитывая описание проекта, устанавливает среду, пути, каталоги и т.д.). То, что я делаю, это настроить все, а затем создать оболочку с помощью:
spawn('bash', ['-i'], {
cwd: new_cwd,
env: new_env,
stdio: 'inherit'
});
После выполнения вы будете в оболочке с новым каталогом (и, в моем случае, средой). Конечно, вы можете изменить bash для любой оболочки, которую вы предпочитаете. Основные отличия от того, что вы изначально просили:
- Существует дополнительный процесс, поэтому...
- вам нужно написать "exit", чтобы вернуться, а затем...
- после существующего, все изменения будут отменены.
Однако для меня эти различия желательны.