If not exists then exit + cmd - cmd

i try to make a loop in a .cmd file.
If test.txt is not exists then i will kill the cmd process.
#echo off
if not exists test.txt goto exit
But this code doesn't work and i don't know how to make a loop every 2 seconds.
Thanks for help.

The command is called exist, not exists:
if not exist test.txt goto :exit
echo file exists
:exit
About your loop:
I am not 100% sure, but I think there is no sleep or wait command in Windows. You can google for sleep to find some freeware. Another possibility is to use a ping:
ping localhost -n 3 >NUL
EDIT:
The Windows Server 2003 Resource Kit Tools contains a sleep.
See here for more information, too

If you need to wait some seconds use standard CHOICE command. This sample code check if file exist each two seconds. The loop ends if file exists:
#ECHO OFF
:CHECKANDWAITLABEL
IF EXIST myfile.txt GOTO ENDLABEL
choice /C YN /N /T 2 /D Y /M "waiting two seconds..."
GOTO CHECKANDWAITLABEL
:ENDLABEL

exit is a key word in DOS/Command Prompt - that's why goto exit
doesn't work.
Using if not exist "file name" exit dumps you out of that batch file.
That's fine if exiting the batch file is what you want.
If you want to execute some other instructions before you exit, change the label to something like :notfound then you can goto notfound
and execute some other instructions before you exit.
(this is just a clarification to one of the examples)

Using the following:
if not exist "file name" goto exit
Results in:
The system cannot find the batch label specified - exit
However using the same command without "goto" works, as follows:
if not exist "file name" exit

Related

Check if file is locked inside a batch file for loop

I have a script that runs through some files and copies them to another location. But the script needs to wait until the file is no longer being written to.
I tried all the solutions here:
How to check in command-line if a given file or directory is locked (used by any process)?
Process a file after a file is finished being written Windows Command Line .bat
BATCH - wait for file to be complete before picking up
But the problem is that they don't work when wrapped in a loop. It always says the file is locked. If the script it cancelled and re-run it correctly finds the file unlocked.
Am I doing something wrong or is there a trick to make this work?
For locking a test file, checkfile.txt, I do:
(
>&2 pause
) >> checkfile.txt
Then the example script to check the file is this:
#echo off
for %%i in (*.txt) do (
:loop
ping localhost -n 5 > nul
echo "check if locked"
powershell -Command "$FileStream = [System.IO.File]::Open('%%i', 'Open', 'Write'); $FileStream.Close(); $FileStream.Dispose()" >NUL 2>NUL || (goto :loop)
echo "NOT locked anymore"
)
You cannot goto in a loop as it will simply break the for loop entirely. Additionally, the exit code or errorlevel is set for the last successful command. In this case being the powershell dispose command. Simply do the loop outside of the code block:
#echo off & setlocal
for %%i in (*.txt) do call :loop %%~i
goto :EOF
:loop
powershell -Command "[System.IO.File]::Open('%1', 'Open', 'Write')">nul 2>&1 && echo %1 not locked || (
echo %1 Locked
("%systemroot%\system32\timeout.exe" /t 3)>nul
goto :loop
)
Note, the conditional operators (and &&) and (or ||) helps to evaluate the exit code without needing to do if and else statements.

How to start of commands with auto response to prompt in batch script

I am trying the following:
start /wait /B "C:\Users\Kiriti_Komaragiri\Desktop\sample" npm i
echo Y
start /wait /B "C:\Users\Kiriti_Komaragiri\Desktop\sample2" npm i
I would like to run the above in the same window with auto response "Y"
Currently, its running only the first command and not the third one. I am not sure why?
Here you go.
echo Y | start /wait /B "C:\Users\Kiriti_Komaragiri\Desktop\sample" npm i
echo Y | start /wait /B "C:\Users\Kiriti_Komaragiri\Desktop\sample2" npm i
More information please. What type of command are you trying to feed the response to? Is it Choice, Set /p, or something else your trying to feed a response to?
Without knowing more, the only suggestion I can make requires the existence of a label before the input is processed in the secondary batch.
A workaround exists whereby you can call and arrive at a label in another Batch by calling a label with the same name in your calling Batch. This allows you to define the value of the input (Whatever form the input takes) in your primary batch, then do as follows (substituting label names, variable names and file paths as appropriate)
-In the Calling (Primary) Batch:
Set ResponseVarName=Y
Call :targetLabel
(whatever code your batch has in between)
REM this is where you make your hack 'Call' to the other batch, without actually 'Calling' the batch itself.
:targetLabel
%userprofile%\desktop\yourotherbatch.bat
exit /b
Just to be sure your absolutely clear, this workaround is utterly dependant on being sent to a specific label after the response is set, BEFORE other commands are executed.
(EDIT-) A couple of example programs to show the concept:
::::::::: %userprofile%\desktop\HomeBatch.bat ::::::::::::::::
#ECHO OFF
:main
Set TestEnvironment=1
Call :targetLabel
:nottarget
ECHO NOT target
pause
exit
:targetLabel
%userprofile%\desktop\OtherBatch.bat npm i
:homeBatch
ECHO returned Home
pause
GOTO main
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::: %userprofile%\desktop\OtherBatch.bat ::::::::::::::::
#ECHO OFF
:NottheTarget
ECHO NOT THE TARGET
pause
exit
:targetLabel
ECHO Found the Target. TestEnvironment=%TestEnvironment% %~1 %~2
pause
Exit /b
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Batch run script when closed

My question is how would I make a batch script instead of closing when the X in the top right is pressed to execute a file called exit.exe.
There are a couple points in this question that are not clear enough:
If you want that when the rigth top X is pressed on the cmd.exe window it not close, but do a different thing instead, then there is no way to achieve such thing with any existent window, that is, with the windows of all existent applications.
If you want to differentiate if the window that execute your Batch file terminated normally or terminated because the user click on the right top X, then the way to achieve that is via a previous "starter" program that execute your Batch file and expects a certain value returned from it. If the returned value is not the expected one, then it is assumed that the window was cancelled via the right top X.
starter.bat:
#echo off
echo Start yourScript.bat:
start "" /W yourScript.bat
echo Value returned from the script: %errorlevel%
if %errorlevel% neq 12345 ECHO execute exit.exe
yourScript.bat:
#echo off
echo I am the script.bat
set /P var=input value:
rem Terminate normally:
exit 12345
the [X] is "out of reach" for cmd. Only way, I can think of is: create another cmd to watch the presence of the current window:
#echo off
title WatchMe
more +7 %~f0 >t2.bat
start "watcher" t2.bat
exit /b
#echo off
:running
tasklist /v|find "WatchMe" >nul &&echo waiting || goto finished
timeout 1 >nul
goto running
:finished
echo "the process has finished

Take the result of previous command safely : Batch (Wait,Sleep,Ping etc..)

I am trying to create a batch file which is doing these things :
move some folder
call another batch file
copy the result of batch file to clipboard
run the imacros (imacros will use the clipboard)
So the important thing is I have to be sure for every step that it is completed. Because every step is attached together.
My question is how can I do that ? I read something about SLEEP, PING, TIMEOUT, PAUSE etc.. But I cannot know very much prons and cons. Could someone give some tips about these commands or which should i use for safe programming ?
Not : I am working on windows xp and windows server 2008
And here is my batch code :
#echo off
set cwd=D:\workset\xx\yyy\
set wp=D:\workset\xx\yyyy\zzzzz\
:: ensure folder exist
mkdir %cwd% > nul 2>&1
mkdir %wp%\done > nul 2>&1
d:
cd %wp%
:export
::echo tidy folder %wp%
for %%i in (xx_to_yy*.zip) do (
move "%%i" "done\%%i"
)
echo call %cwd%aaa_bbb_export.bat
call %cwd%aaa_bbb_export.bat 5555
#echo off
for %%i in (xx_to_yy*.zip) do (
echo %wp%%%i | clip
move "%%i" "done\%%i"
)
#echo off
:finish
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" http://www.google.com
ping 127.1.1.1
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" imacros://run/?m=yyy.iim
Using the pause and echo command is a great way to debug a piece of scrip in batch.
Simply add:
Echo Task Complete: [Description] : Continue ?&>nul pause
At the end of every task. That way, you can check if everythings fine before giving the all clear for you batch file to continue. Later on, you'll learn to do error checking in batch files, in which case you could do something similar with an error message and include soloutions as options.
Edit:
If you wish to automate the script, so that it doesn't need user input, and instead attempts to check ikf an error occured you could either:
Check manualy, that is 1: check if folder has moved, 2: check if other batch file did what it needed (create new files etc.) 3: check if clipboard has suffiecent lines to be result of batch files (maybe clear it at the start) and lastly, check if imacros did what was needed
Check if commands were succeful. (redirec errors to a text file and then see if they were any.
Since, I don't know exactly what you are doing, I can only help you wit case 2 (though 1 would be better). You redirect the errors as so:
command [parameters] 2>>errors.log
And at the end of every section:
set /p error=<errors.log
if defined error (
Echo An Error Occured : Last Step == [Step Description]
ECHO ---------- RUN : %Date% %Time% ----------
type errors.log >> error-log.txt
del errors.log
if "%~1"=="RESTART" (
Echo Error Occured Two Times in a Row . . .
Echo Exiting in 20 seconds . . .
Exit /b 9
)
Echo Restarting procedure in 60 seconds . . .
sleep 60
Start %~f0 "RESTART"
Exit
)
The above code will check if there were any errors, add them to a log called error-log.txt. If there is an error, it will restart and if there is an error again, it will exit. There will be a small pause before either of these events, incase you want to cancel it (simply close)
Hope you found this helpful,
Mona.
First option is, after each "critical" command, check for errorlevel
copy someThing someWhere
if errorlevel 1 (
rem something goes bad
goto somewhereToHandleIt
)
Alternatively, you can add code to check that the operation was sucessful, testing everything is where it is supossed to be. But first option is usually better. Trust the system, it will do the work and report when problems found.

What is the equivalent to $? in Windows?

Does anybody know what is the equivalent to $? in Windows command line? Is there any?
EDIT: $? is the UNIX variable which holds the exit code of the last process
You want to check the value of %ERRORLEVEL%.
Windows Batch Files
%ERRORLEVEL% Returns the error code of
the most recently used command. A non
zero value usually indicates an error.
http://technet.microsoft.com/en-us/library/bb490954.aspx
Windows Powershell
$?
Contains True if last operation succeeded and False otherwise. And
$LASTEXITCODE
Contains the exit code of the last Win32 executable execution.
http://blogs.msdn.com/powershell/archive/2006/09/15/ErrorLevel-equivalent.aspx
Cygwin Bash Scripting
$? Expands to the exit status code of
the most recently executed foreground
program.
http://unix.sjcc.edu/cis157/BashParameters.htm
Sorry to dredge up an old thread, but it's worth noting that %ERRORLEVEL% doesn't get reset with every command. You can still test "positive" for errorlevel after several lines of subsequent--and successful--batch code.
You can reliably reset errorlevel to a clean status with ver. This example works with UnxUtils for a more Linux-ish directory listing. The reset might seem extraneous at the end, but not if I need to call this script from another.
:------------------------------------------------------------------------------
: ll.bat - batch doing its best to emulate UNIX
: Using UnxUtils when available, it's nearly unix.
:------------------------------------------------------------------------------
: ll.bat - long list: batch doing its best to emulate UNIX
: ------------------------------------
: zedmelon, designer, 2005 | freeware
:------------------------------------------------------------------------------
#echo off
setlocal
: use the UnxUtil ls.exe if it is in the path
ls.exe -laF %1 2>nul
if errorlevel 1 (
echo.
echo ----- ls, DOS-style, as no ls.exe was found in the path -----
echo.
dir /q %1
)
: reset errorlevel
ver>nul
endlocal
Feel free to use this. If you haven't seen UnxUtils, check 'em out.
#echo off
run_some_command
if errorlevel 2 goto this
if errorlevel 1 goto that
goto end
:this
echo This
goto end
:that
echo That
goto end
:end
%errorlevel%

Resources