単一のバッチファイルコマンドのディレクトリを一時的に変更する

単一のバッチファイルコマンドのディレクトリを一時的に変更する

シェル スクリプトでは、ディレクトリからコマンドを実行する必要がある場合、サブシェルを使用して元のコンテキストに戻ることができます。

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

これはWindowsのバッチファイル(またはcmdファイル)で実行できますか?

バッチファイルで同じことを実行すると、新しいディレクトリに残ります。

できます:

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

しかし、popd は の成功に依存しますcommand

何か案は?

答え1

もし、するなら:

pushd \windows && foobar && popd

(あなたが述べているように) \windows フォルダに残ります。次を試してください:

pushd \windows & foobar & popd

そして、出発点に戻るはずです。

答え2

デフォルトでは、Windows バッチ ファイルは親シェルのコンテキストで実行されます (これは明示的な指定sourceが必要な Unix ユーザーにとっては珍しいことですが、MS-DOS ではこれが唯一の可能性でした)。つまり、ディレクトリの変更と環境変数は元の対話型シェルにも影響します。

setlocalスクリプトの先頭に配置すると、スクリプトが独自のコンテキストで実行されるようになり、cdスクリプト内で安全に使用できるようになります。

答え3

grawity が前述したように、後者はそのようなディレクトリが存在しない場合は失敗する可能性があるため、pushd \windows && (foobar & popd)よりも適切に機能します。pushd \windows & foobar & popd

また、 とsetlocalを使用するとendlocal、複数のローカル環境を持つことができるため、たとえば次のようになります。

setlocal

cd dir

command

endlocal

これで元のディレクトリに戻ります。

答え4

setlocalgrawityさんのバッチスクリプトの先頭に/ブロックを置くという提案には賛成ですが、複数のネストされたsetlocal/endlocalブロックを持つことができるという事実を追加したいと思います。そのため、質問に対するより適切な回答は次のようになるかもしれません。

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

そしてもちろん、コマンドをcdtoの場合にのみ実行したい場合は、dir2成功したとしましょうcddir2&&command

setlocal/endlocalブロックはローカライズされた環境を作成するので、そのようなブロックで設定または変更した変数は、 の後に以前の値に戻ることに注意してくださいendlocal

関連情報