Alterar temporariamente o diretório para o comando de arquivo em lote único


19

Em scripts de shell, se eu precisar executar um comando a partir de um diretório, podemos usar um subshell para garantir que eu retorne ao contexto original:

(cd temporary/new/directory ; command)
# now I am still in original directory

Isso pode ser feito em arquivos em lotes do Windows (ou arquivos cmd)

Fazer o mesmo em arquivos em lote me deixa no novo diretório.

Eu posso fazer:

pushd temporary\new\directory && command && popd

Mas o popd depende do sucesso de command.

Alguma ideia?


Como você está chamando seu "arquivo em lote" ou "arquivo cmd"? Se você colocar um comando cd em um script de shell e executar esse script (não for originado), o diretório de trabalho atual do shell de chamada não será alterado.
— 22811 garyjohn

Só para ficar claro, isso se refere aos arquivos em lotes do Windows.
— Greg

É um script que executa vários comandos em diferentes partes de uma árvore de diretórios. Alguns dos comandos operam apenas no diretório atual. Retornar ao diretório original ajuda a simplificar os dados que controlam o script. Você está sugerindo criar um arquivo em lotes separado para cada diretório em que eu preciso fazer chamadas?
— Greg

Pelo que me lembro, você se referiu a scripts de shell e não mencionou o Windows na sua pergunta original, então assumi incorretamente que você estava usando um sistema semelhante ao Unix. Agora eu entendo.
— 3051111

Sim, desculpe, eu percebo que não era clara (embora eu acho que 'batch-file' era um :-P dica)
— Greg

Respostas:


21

Se você fizer:

pushd \windows && foobar && popd

você será deixado (como você declara) na pasta \ windows. Experimentar:

pushd \windows & foobar & popd

e você deve voltar aonde começou.


11
Ah, um único e comercial é o equivalente a ponto e vírgula em sh. Perfeito. (e uma referência: ss64.com/nt/syntax-conditional.html )
— Greg

6
É bom lembrar que cd/ pushdàs vezes falha (se o diretório não existir, por exemplo). pushd \windows && (foobar & popd)pode ser mais confiável
— grawity

16

Por padrão, os arquivos em lotes do Windows são executados no contexto do shell pai (o que é incomum para usuários do Unix, onde sourceé necessário um explícito , mas era a única possibilidade no MS-DOS). Isso significa que mudanças de diretório e variáveis ​​de ambiente também afetam o shell interativo original.

Coloque setlocalna parte superior do seu script para executá-lo em seu próprio contexto - você pode usá-lo com segurança cddentro do script.


Obrigado, isso parece o que eu preciso - vou verificá-lo quando tiver acesso a uma máquina Windows. Isso afetaria os subcomandos usando parênteses?
— Greg

11
@ Greg: Parece que ( )apenas agrupa comandos juntos, mas ainda os executa no contexto pai. (setlocal & cd foo & bar)não funciona; em vez disso pushd foo && (bar & popd)seria necessário.
— grawity

4

Como o grawity mencionado anteriormente, pushd \windows && (foobar & popd)funcionaria melhor do que pushd \windows & foobar & popdporque o último pode falhar se não houver esse diretório.

Além disso, usar setlocale endlocalpermitir que você tenha vários ambientes locais; por exemplo, você pode ter:

setlocal

cd dir

command

endlocal

Agora você estaria de volta ao seu diretório original.


3

Você pode usar cd -para voltar ao diretório de trabalho anterior. E use em ;vez de &&, então os comandos subseqüentes não dependerão do sucesso dos comandos anteriores.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc

Atualizei a pergunta para esclarecer que estou perguntando sobre o script de lote / shell do Windows. Eu sei como fazê-lo em um shell sh-like :)
— Greg

Como BillP3rd apontou o equivalente a ';' em arquivos em lote é '&'.
— Greg

Ah desculpa. Seu uso de barras me fez pensar que era o UNIX.
— bahamat 30/07/11

1

Aplaudo a sugestão de grawity de colocar setlocalno início do script em lote, mas acrescentaria o fato de que você pode ter vários blocos aninhados setlocal/ endlocal, para que uma resposta mais relevante à pergunta possa ser

@echo off
setlocal
cddir1
  ...
setlocal
cddir2
command
endlocal
:: Now I am back indir1
  ...

E, é claro, se você deseja que o comando seja executado apenas se o cdto dir2for bem-sucedido, digamos .cddir2&&command

Observe que o bloco setlocal/ endlocalcria um ambiente localizado; portanto, qualquer variável que você definir ou alterar nesse bloco voltará ao seu valor anterior após o endlocal.


0

Você pode salvar o diretório atual em uma variável. Mude e mude de volta, dependendo do valor de retorno do comando. BTW,% CD% retorna seu DIR atual.

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.