2017-03-17 10 views
1

私はバッチファイルが実行後に既知の場所に移動する方法を探しています。自己動く - 最も適切な名前であるように思われましたが、私はそこに専門用語があると確信しています。の後、バッチファイルを他のすべてのコードが実行された後に移動したいとします。自己移動バッチファイル

move "C:\temp\move_me.bat" "D:\temp\move_me.bat" 

ここで、move_me.batは、d:\ tempに移動するためにc:\ tempに配置された氏名バッチファイルです。

私は、バッチファイルが場所を移動していても

The batch file cannot be found.

エラーが発生します。だから少し混乱している。エラーを抑制する必要があるのですか、バッチファイルをコピーしてソースを削除するのが最善でしょうか?または、これを行うためのより良い方法がありますか?

答えて

3

ザ・Windowsのコマンドプロンプトcmdは、それがラインによってファイルの行からそれらを読み込み、メモリ上にキャッシュしないバッチファイルを実行します。したがって、ファイルがこれ以上見つからないため、moveコマンドが完了するとすぐにエラーが表示されます。

あなたはエラーを抑制するために、このようなバッチファイルを呼び出すことができます。

"C:\temp\move_me.bat" 2> nul 

しかし、これは意図せずも、他のすべてのエラーメッセージをsupresses。

とにかく、おそらく次のようなアプローチはあなたのために働く - これは、スクリプトC:\temp\move_me.batです:まず

if /I "%~dp0"=="D:\temp\" exit /B 
rem // (some other code here...) 
copy "%~f0" "D:\temp\%~nx0" 
"D:\temp\%~nx0" & del "%~f0" 

D:\temp\と照合され、現在実行バッチファイルの場所。等しい場合、バッチファイルは直ちに終了します。

最後に、(%~f0 によってアクセスされる)元のバッチファイルがコピーされ(、同じままであるファイル名、%~nx0)新しい位置D:\tempに(移動しません)。

次の行は、新しい場所からバッチファイルを実行しますが、呼び出し元のバッチスクリプトに戻るにはcallを使用しませんが、これはわれわれが望むものではありません。& operatorは、前のコマンドが終了したときに次のコマンドを実行させます。 callは使用されていませんが、次のコマンドは、行全体がすでに読み取られ、cmdによって解析されているので実行されます。しかし、実行制御はバッチファイルの新しいインスタンスにあるため、エラーメッセージThe batch file cannot be found.は表示されなくなりました。

上記のifクエリは、バッチファイルのコピーの実行を直ちに終了するので、他のコードは2回実行されません。

rem // (some other code here...) 
copy "%~f0" "D:\temp\%~nx0" > nul || exit /B 
"D:\temp\%~nx0" & del "%~f0" 

> nul portionは(含む表示メッセージを抑制します。あなたは、コピーしたバッチファイルの実行をスキップifコマンドラインを削除し、これを取得するためにcopyコマンドラインを変更したくない場合は

要約1 file(s) copied.)。 || operatorは、コピーが失敗した場合にのみ、次のコマンドを実行します。元のバッチファイルが実行されると、コピーは期待どおりに行われます。コピーされたバッチファイルが実行されると、copyはバッチファイルを自分自身にコピーしようとします。メッセージThe file cannot be copied onto itself.(抑制されたファイルは> nul)とexit /Bコマンドの実行中のエラー(||のため)最後の行は実行されません。


moveでも同様の動作が得られます。これに関連するコードは次のようになります。

if /I "%~dp0"=="D:\temp\" exit /B 
rem // (some other code here...) 
move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0" 

それとも、あなたが移動するスクリプトのためにスキップされない他のコードたい場合:

rem // (some other code here...) 
if /I not "%~dp0"=="D:\temp\" move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0" 

ifクエリはとは対照的に、moveとして必要ですcopyは、送信元と送信先が等しい場合はエラーを返しません。


これは、移動したバッチファイルの包括的なソリューションであり、後で移動したバッチファイルを制御します。コードはどのようなバッチファイルのインスタンスで実行されているものを見つけるために、すべての説明の発言を見てみましょう:

@echo off 

rem // Define constants here: 
set "_TARGET=D:%~pnx0" & rem /* (this defines the movement destination; 
         rem  in your situation, the original batch file is 
         rem  `C:\temp\move_me.bat`, so the target file is 
         rem  `D:\temp\move_me.bat` (only drive changes)) */ 

rem // (code that runs for both batch file instances...) 
echo Batch file: "%~f0" 
echo [executed by both files before the movement check] 

rem // Check whether current batch file is the moved one: 
if /I "%~f0"=="%_TARGET%" (

    rem // (code that runs for the moved batch file instance only...) 
    echo Batch file: "%~f0" 
    echo [executed only by the moved file] 

) else (

    rem // (code than runs for the original batch file instance only...) 
    echo Batch file: "%~f0" 
    echo [executed only by the original file] 

    rem // Actually move the batch file here, then give control to the moved one: 
    > nul move "%~f0" "%_TARGET%" 
    "%_TARGET%" 

    rem /* (code that runs for the original batch file instance only; 
    rem  this is run after the moved batch file has finished; 
    rem  you must not use `goto` herein as the target label cannot be found, 
    rem  because the original file does no longer exist at this point!) */ 
    echo Batch file: "%~f0" 
    echo [executed only by the original file, but after the moved one has finished] 

) 

rem // (code that runs for the moved batch file instance only...) 
echo Batch file: "%~f0" 
echo [executed only by the moved file after the movement check] 

exit /B 

は コードのブロック (/ )と継続的なライン ^を括弧に入れ

1)注は、次のように考えられています単一のコマンドライン:

(
    echo This entire parenthesised block is 
    echo considered as a single command line. 
) 
echo This continued line &^
echo as well.

2)は、引数の参照はとすぐに、コマンド・ライン・Oとして解決されることに注意してくださいrブロックは読み込まれ、解析されるため、実際に実行される前にブロックされます。

0

バッチファイルは、一度にメモリに読み込むのではなく、行単位で実行されます。 moveコマンドの後にコマンドがありますか?

しかし、バッチファイルには、別のバッチファイルを呼び出すとバッチファイルがオーバーレイされるという特徴もあります。

だから、あなたで逃げることができるかもしれません。先に

if "%1" == "continuation" goto :continuation 

REM interesting things go here 

move "C:\Temp\move_me.bat" "D:\Temp\move_me.bat" 
"D:\Temp\move_me.bat" continuation 

:continuation 
REM more interesting things go here 

またコピーバッチファイルと継続が元のコピーを削除しています。

または、最初ののように、バッチファイル自体をコピー先にコピーして(自分自身を削除してください)それは理解しやすいでしょう。

+0

'move'の後の行はもう認識されません。おそらく、あなたは 'move'を' copy'に変更して ':continuation'セクションで元のバッチファイルを' del'で削除することができます... – aschipfl

+0

... 'move'を保つだけで、次の行を'& ' 、それは認識されるべきです... – aschipfl

関連する問題