윈도우는 명령 프롬프트 cmd
는 라인 1하여 파일 줄에서를 읽고, 메모리에 캐시하지 배치 파일을 수행합니다. 따라서 파일을 더 이상 찾을 수 없기 때문에 move
명령이 완료되면 오류 메시지가 나타납니다.
"C:\temp\move_me.bat" 2> nul
을하지만이 또한 실수로 다른 모든 오류 메시지를 진압 :
당신은 오류를 억제하기 위해이 같은 배치 파일을 호출 할 수 있습니다.
어쨌든, 아마도 다음과 같은 방법을 사용하면 작동 -이 스크립트 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
2 액세스) 원래의 배치 파일 복사 (동일하게 유지 파일 이름, %~nx0
) 새 위치 D:\temp
로 (이동하지 않음).
다음 줄은 배치 파일을 새 위치에서 실행하지만 호출 배치 스크립트로 돌아 가기 위해 필요한 call
을 사용하지 않고 있지만 이는 원하는 바가 아닙니다.&
operator은 이전 명령이 완료 될 때 다음 명령을 실행하게합니다. call
은 사용되지 않지만 전체 행이 이미 읽혀지고 cmd
에 의해 구문 분석되기 때문에 다음 명령이 계속 실행됩니다. 그러나 이제 실행 제어가 배치 파일의 새 인스턴스에 있으므로 오류 메시지 The batch file cannot be found.
이 더 이상 나타나지 않습니다.
위의 if
쿼리는 배치 파일의 복사본을 즉시 종료하므로 다른 코드가 두 번 실행되지 않습니다. 복사 한 배치 파일의 실행을 생략하지 않으려는 경우
는 if
명령 줄을 제거하고이 얻을 수있는 copy
명령 줄을 수정합니다 > nul
portion 디스플레이 메시지를 억제
rem // (some other code here...)
copy "%~f0" "D:\temp\%~nx0" > nul || exit /B
"D:\temp\%~nx0" & del "%~f0"
합니다 (를 포함하여 요약 1 file(s) copied.
). ||
operator은 복사가 실패 할 경우에만 다음 명령을 실행합니다. 따라서 원래의 배치 파일이 실행되면 예상대로 복사가 수행됩니다. 복사 된 배치 파일이 실행될 때 copy
은 배치 파일을 자체에 복사하려고 시도합니다. 이는 메시지 The file cannot be copied onto itself.
(> nul
에 의해 표시되지 않음)을 발생시키고 exit /B
명령 (||
으로 인해)이 배치 파일에서 나가기 때문에 오류가 발생합니다. 마지막 줄은 실행되지 않습니다.
move
을 사용해도 동일한 동작을 얻을 수 있습니다.
rem // (some other code here...)
if /I not "%~dp0"=="D:\temp\" move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0"
if
쿼리는 달리, move
필요하다 : 당신이 이동 스크립트 생략하지 않는 다른 코드를 원하는 경우,
if /I "%~dp0"=="D:\temp\" exit /B
rem // (some other code here...)
move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0"
을 또는 그래서 관련 코드는 다음과 같습니다 소스와 대상이 동일하면 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 블록은 읽히고 파싱되므로 실제 실행되기 전에 차단됩니다.
'이동'이후의 줄은 더 이상 인식되지 않습니다. 아마도'move'를'copy'로 바꾸고 원래의 배치 파일을': continuation' 섹션에서'del'로 삭제할 수 있습니다 ... – aschipfl
... 또는'move'를 유지하면서'&' , 그러면 인식되어야합니다 ... – aschipfl