If command in Batch file - if-statement

I am wondering why my code works this way:
If exist c:\work\first\food.txt (echo win) else (echo fail)
but not like this:
If exist c:\work\first\food.txt (echo food.txt is in C:\work\first) else (echo fail)
I'm using Notepad++ to write this and "in" and c:\work\first are highlighted blue like the other commands if that helps.

Your code works fine. There is no need to escape anything in that particular line.
However double quotes are needed in several cases - where spaces are in the path or & characters etc.
If exist "c:\work\first\food.txt" (echo food.txt is in C:\work\first) else (echo fail)

Related

How to use a CMD command in c++?

I want to use this cmd command
ROBOCOPY D:\folder1 D:\folder2 /S /E
with conditions to copy the contents of folder1 to folder2
if(i == 1)
and,
if(i == 2)
ROBOCOPY D:\folder3 D:\folder4 /S /E
to copy the contents of folder3 to folder4
what should i do?
"what should i do?"
You simply do this (using the std::system() function):
#include <cstdlib>
// ...
if(i == 1) {
std::system("ROBOCOPY D:/folder1 D:/folder2 /S /E");
}
else if(i == 2) {
std::system("ROBOCOPY D:/folder3 D:/folder4 /S /E");
}
Note that for string literals like "D:\folder3", you'll need to escape '\' characters, with another '\': "D:\\folder3".
Or even two more, depending on the interpreting command shell (should work on windows cmd without doing so): "D:\\\\folder3".
The easier way though, is to use the simpler to write '/' character, that's accepted for specifying windows pathes lately as well.
The simplest way is to call the standard library function system: http://www.cplusplus.com/reference/cstdlib/system/
If you need more flexibility, http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx CreateProcess is the thing to go for - the STARTUPINFO argument lets you do things like pass it custom input and capture its output too.

csh inline if statements

I'm trying to add a script to check conditions before executing a command in my .cshrc file. This checker script returns 0 if the conditions are insufficient, and 1 otherwise. (I realize this is backwards of convention, but I thought it would be easier for if statements.)
Here is what I've tried, replacing the command with echo "ok":
./checker.sh && echo "ok"
Echoes "ok" even though checker.sh returns 0.
test ./checker.sh && echo "ok"
Echoes "ok" even though checker.sh returns 0, but also suppresses error messages in checker.sh.
if ( ./checker.sh ) then echo "ok" endif
Throws an if-statement syntax error.
I want to turn this into an alias, hence the one-line constraint, e.g.
alias doAction './checker.sh && echo "ok"'
How does one accomplish this with (t)csh without directly calling the command in the checker script?
Thanks!
I changed the script to exit 0 when there is NO problem, and exit a nonzero number when there is a problem. Then
./checker.sh && echo "ok"
behaves as desired...
Note to others who may read this: the above "test" construct is not equivalent to the C-style if-statement
if(./checker.sh){
echo "ok"
}

Batch Script Input Problems

I have two questions regarding a batch script I'm working on. I realize that batch script questions are common but haven't found an answer to my exact question so I thought I'd try asking. The problematic areas are the user input sections on the menus.
There are two problems: 1) Input entered that is not one of the specified choices will cause the script to jump to random areas. And 2) some sections that use external programs are not taking the user %input% even when I know the syntax and flag use would normally be correct (as in, I can run them manually... so for some reason the input isn't capturing on them).
First issue example:
:MenuOne
echo Select one of the following options:
echo 1) x
echo 2) y
echo Q) Quit
set INPUT=
set /P INPUT=[1,2,Q]: %=%
If "%INPUT%"=="1" goto xoption
If "%INPUT%"=="2" goto yoption
If /I "%INPUT%"=="Q" goto Quit
:xoption
#REM Here goes a lot more submenus and/or options that actually run tools via cmd.
:yoption
#REM Again, menus and/or tools being invoked, in a listed menu, designed like above.
:Quit
echo Quitting...
exit
If a user types "b" at the selection prompt, I would love for the script to give an error and repeat the menu. Instead it jerks around other menus. I'm guessing that I need some ELSE statements? Does anyone have an example that I can use to accomplish this?
Second issue of some commands not using the %input% properly and returning an error as though it never received the %input%.
set /P INPUT=[Testone Input]: %testone%
set /P INPUT=[Testtwo Input]: %testtwo%
commandtorun.exe -f %testone% -h %testtwo%
Thanks!
Better to use choice (http://ss64.com/nt/choice.html) because it will persist until you set the correct input
CHOICE /C XYQ /M "Select of the following options [X,Y,Q]"
if errorlevel 1 goto :x
if errorlevel 2 goto :y
uf errorlevel 3 goto :q
Yet it's still possible to be done with IFs
set INPUT=
set /P INPUT=[1,2,Q]: %=%
If "%INPUT%"=="1" goto xoption
If "%INPUT%"=="2" goto yoption
If /I "%INPUT%"=="Q" goto Quit
rem -- will be executed only if the all the above are not true
goto :eof
For the second problem..You are not using SET /P correctly (the name of the variable should be in the front) , or you are trying something that I don't understand (where input variable is used):
set /P testone=[Testone Input]:
set /P testtwo=[Testtwo Input]:
commandtorun.exe -f %testone% -h %testtwo%
In your program as written, all your choices will fall through to the next one. If no relevant choice is entered, it will run :xoption and :yoption. Each of those should probably return to the menu after executing:
:MenuOne
echo Select one of the following options:
echo 1) x
echo 2) y
echo Q) Quit
set INPUT=
set /P INPUT=[1,2,Q]: %=%
If "%INPUT%"=="1" goto xoption
If "%INPUT%"=="2" goto yoption
If /I "%INPUT%"=="Q" goto Quit
echo Invalid selection.
echo.
goto MenuOne
:xoption
#REM Here goes a lot more submenus and/or options that actually run tools via cmd.
goto MenuOne
:yoption
#REM Again, menus and/or tools being invoked, in a listed menu, designed like above.
goto MenuOne
A real simple way to ensure a valid selection is made is to use the choice command instead of set /P. That will force the user to enter a value:
choice -c 12Q
echo %errorlevel%
The choice command will return the index of the selected character (1, 2 or 3 in the above example). A bonus is that it is case-insensitive, so you don't have to worry about checking both Q and q.

Batch File IF Else info

I am attempting to get my script to GOTO Manual if the criteria below is not met .
How ever if the get_info.bat fails and throws a error my script stops and just displays the batch file error (calling python script) . It works when the condtions are met but not on error / not met.
for /f "tokens=1* delims=" %%x in ('get_info.bat ^| find /i "agentVersion: 4"') do #set HPSAAGT=%%x
ECHO %HPSAAGT%
IF "%HPSAAGT%"=="agentVersion: 45.0.31322.0" (set AGTVERSION=45.0.31322.0) ELSE IF "%HPSAAGT%"=="agentVersion: 40.0.0.1.106" (set AGTVERSION=40.0.0.1.106) ELSE (GOTO MANUAL)
The code works fine for me... it may be a problem with your variable. Try echo -%HPSAAGT%- to see if there are extra spaces in your variable.
Additionally, if you just want the version number, you should just use string manipulation, example:
echo %HPSAAGT:~14%
would result in
45.0.31322.0
if a==b (echo ab) else if b==c (echo bc) else (goto manual)
rem some more code
pause
:manual
echo Manual
works fine.
Is there possibly a misspelling in your Label :manual ?

Can I have an IF block in DOS batch file?

In a DOS batch file we can only have 1 line if statement body? I think I found somewhere that I could use () for an if block just like the {} used in C-like programming languages, but it is not executing the statements when I try this. No error message either. This my code:
if %GPMANAGER_FOUND%==true(echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7
Strangely neither "GP Manager is up" nor "GP Manager is down" gets printed when I run the batch file.
You can indeed place create a block of statements to execute after a conditional. But you have the syntax wrong. The parentheses must be used exactly as shown:
if <statement> (
do something
) else (
do something else
)
However, I do not believe that there is any built-in syntax for else-if statements. You will unfortunately need to create nested blocks of if statements to handle that.
Secondly, that %GPMANAGER_FOUND% == true test looks mighty suspicious to me. I don't know what the environment variable is set to or how you're setting it, but I very much doubt that the code you've shown will produce the result you're looking for.
The following sample code works fine for me:
#echo off
if ERRORLEVEL == 0 (
echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7
Please note a few specific details about my sample code:
The space added between the end of the conditional statement, and the opening parenthesis.
I am setting #echo off to keep from seeing all of the statements printed to the console as they execute, and instead just see the output of those that specifically begin with echo.
I'm using the built-in ERRORLEVEL variable just as a test. Read more here
Logically, Cody's answer should work. However I don't think the command prompt handles a code block logically. For the life of me I can't get that to work properly with any more than a single command within the block. In my case, extensive testing revealed that all of the commands within the block are being cached, and executed simultaneously at the end of the block. This of course doesn't yield the expected results. Here is an oversimplified example:
if %ERRORLEVEL%==0 (
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
)
This should provide var3 with the following value:
blue_cheese
but instead yields:
_
because all 3 commands are cached and executed simultaneously upon exiting the code block.
I was able to overcome this problem by re-writing the if block to only execute one command - goto - and adding a few labels. Its clunky, and I don't much like it, but at least it works.
if %ERRORLEVEL%==0 goto :error0
goto :endif
:error0
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
:endif
Instead of this goto mess, try using the ampersand & or double ampersand && (conditional to errorlevel 0) as command separators.
I fixed a script snippet with this trick, to summarize, I have three batch files, one which calls the other two after having found which letters the external backup drives have been assigned. I leave the first file on the primary external drive so the calls to its backup routine worked fine, but the calls to the second one required an active drive change. The code below shows how I fixed it:
for %%b in (d e f g h i j k l m n o p q r s t u v w x y z) DO (
if exist "%%b:\Backup.cmd" %%b: & CALL "%%b:\Backup.cmd"
)
I ran across this article in the results returned by a search related to the IF command in a batch file, and I couldn't resist the opportunity to correct the misconception that IF blocks are limited to single commands. Following is a portion of a production Windows NT command script that runs daily on the machine on which I am composing this reply.
if "%COPYTOOL%" equ "R" (
WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using RoboCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
%TOOLPATH% %SRCEPATH% %DESTPATH% /copyall %RCLOGSTR% /m /np /r:0 /tee
C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Robocopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
) else (
WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using XCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
call %TOOLPATH% "%USERPROFILE%\My Documents\Outlook Files\*" "%USERPROFILE%\My Documents\Outlook Files\_backups" /f /m /v /y
C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Xcopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
)
Perhaps blocks of two or more lines applies exclusively to Windows NT command scripts (.CMD files), because a search of the production scripts directory of an application that is restricted to old school batch (.BAT) files, revealed only one-command blocks. Since the application has gone into extended maintenance (meaning that I am not actively involved in supporting it), I can't say whether that is because I didn't need more than one line, or that I couldn't make them work.
Regardless, if the latter is true, there is a simple workaround; move the multiple lines into either a separate batch file or a batch file subroutine. I know that the latter works in both kinds of scripts.
Maybe a bit late, but hope it hellps:
#echo off
if %ERRORLEVEL% == 0 (
msg * 1st line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue1
)
:Continue1
If exist "C:\Python31" (
msg * 2nd line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue2
)
:Continue2
If exist "C:\Python31\Lib\site-packages\PyQt4" (
msg * 3th line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue3
)
:Continue3
msg * 4th line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue4
)
:Continue4
msg * "Tutto a posto" rem You can relpace msg * with any othe operation...
pause