Alterar o diretório de trabalho no meu contexto shell atual ao executar o script do Node


114

Estou tentando alterar o diretório de trabalho do meu script Node.js quando ele é executado a partir de um script bin. Eu tenho algo como o seguinte:

#!/usr/bin/env node
process.chdir('/Users')

Quando eu executo este arquivo com ./bin/nodefile, ele sai, mas o diretório de trabalho do contexto do shell atual não mudou. Eu também tentei shelljs , mas isso também não funciona.

Qual é a melhor maneira de fazer isso? Eu entendo que está funcionando, mas é apenas um processo separado.


que evidência você tem de que o cwd não mudou? Lembre-se de que os caminhos usados ​​em require () e no cwd são duas coisas diferentes.
jeesty

Existe uma maneira de fazer isso no Windows?
Phillip

Respostas:


146

A maneira correta de mudar de diretório é com process.chdir(directory). Aqui está um exemplo da documentação :

console.log('Starting directory: ' + process.cwd());
try {
  process.chdir('/tmp');
  console.log('New directory: ' + process.cwd());
}
catch (err) {
  console.log('chdir: ' + err);
}

Isso também pode ser testado no REPL do Node.js:

[monitor@s2 ~]$ node
> process.cwd()
'/home/monitor'
> process.chdir('../');
undefined
> process.cwd();
'/home'

Opa. Sim, esse é o comando que estou usando. No entanto, quando o uso em um script simples, ele ainda parece não funcionar (uma vez que o script sai, ainda estou no diretório antigo). Se eu chamar process.cwd (), ele diz que estou no diretório, mas meu terminal se eu chamar pwd diz que estou em algo diferente. Porque é um processo diferente?
Jonovono

10
O método altera o diretório de trabalho atual do processo , não o shell. Pelo que eu sei, alterar o cwd externo de um processo em execução é bastante complexo e não é recomendado. Qual é o seu motivo para querer fazer isso?
hexacianida

3
Hmm. Ok, obrigado. Bem, o motivo pelo qual quero fazer isso é porque estou fazendo um aplicativo de terminal para organizar meus projetos. Então, basicamente, eu quero ser capaz de listar meus projetos e alterar facilmente a localização atual do shell para isso. Agora que penso sobre isso, vou ver como z ( github.com/rupa/z ) faz isso. Embora isso seja feito em bash. Eu poderia fazer isso em applecript?
Jonovono

@hexacyanide obrigado por adicionar estava incomodando porque as mudanças não estavam alinhadas
Eugen Sunic

33

Não existe um método integrado para o Node alterar o CWD do shell subjacente que executa o processo do Node.

Você pode alterar o diretório de trabalho atual do processo do por meio do comando process.chdir().

var process = require('process');
process.chdir('../');

Quando o processo Node existir, você se encontrará de volta ao CWD em que iniciou o processo.


14

O que você está tentando fazer não é possível. A razão para isso é que em um sistema POSIX (Linux, OSX, etc), um processo filho não pode modificar o ambiente de um processo pai. Isso inclui modificar o diretório de trabalho do processo pai e as variáveis ​​de ambiente.

Quando você está na linha de comando e você vai para executar o seu nó do script, o seu processo atual ( bash, zsh, qualquer que seja) gera um novo processo que tem o seu próprio ambiente, normalmente uma cópia do seu ambiente atual (é possível alterar esta via chamadas de sistema ; mas isso está além do escopo desta resposta), permitindo que o processo faça o que for necessário em isolamento completo. Quando o subprocesso termina, o controle é devolvido ao processo do seu shell, onde o ambiente não foi afetado.

Existem muitos motivos para isso, mas, por um lado, imagine que você executou um script em segundo plano (via ./foo.js &) e, à medida que era executado, ele começou a alterar seu diretório de trabalho ou sobrescrever o seu PATH. Isso seria um pesadelo.

Se você precisar realizar algumas ações que requerem a alteração do diretório de trabalho do seu shell, você precisará escrever uma função em seu shell. Por exemplo, se você estiver executando o Bash, pode colocar isso em ~/.bash_profile:

do_cool_thing() {
  cd "/Users"
  echo "Hey, I'm in $PWD"
}

e então essa coisa legal é possível:

$ pwd
/Users/spike
$ do_cool_thing
Hey, I'm in /Users
$ pwd
/Users

Se você precisa fazer coisas mais complexas além disso, você sempre pode chamar seu script nodejs a partir dessa função.

Esta é a única maneira de realizar o que está tentando fazer.


10

Resposta curta: maneira não (fácil?), Mas você pode fazer algo que atenda ao seu propósito.

Eu fiz uma ferramenta semelhante (um pequeno comando que, dada a descrição de um projeto, define ambiente, caminhos, diretórios, etc.). O que eu faço é configurar tudo e, em seguida, gerar um shell com:

spawn('bash', ['-i'], {
  cwd: new_cwd,
  env: new_env,
  stdio: 'inherit'
});

Após a execução, você estará em um shell com o novo diretório (e, no meu caso, ambiente). Claro, você pode alterar o bash para qualquer shell de sua preferência. As principais diferenças em relação ao que você pediu originalmente são:

  • Existe um processo adicional, então ...
  • você tem que escrever 'sair' para voltar, e então ...
  • depois de existir, todas as alterações são desfeitas.

No entanto, para mim, essas diferenças são desejáveis.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.