I'm not very familiar with BAT files but I have a file that runs a sqlplus query, returns the row count, and if it is greater than 0, run another bat file. I feel like I'm almost there but I keep getting this error:
%%a was unexpected at this time
#echo off
for /f "delims=" %%a in (
'sqlplus USER/PASS#OMP1 #VoiceBlockTrig.SQL'
) do set rowcount=%%a
if %ROWCOUNT% GTR 0 (
c:\SQLTRIGGERS\VoiceBlkAutoationBAT.bat
)
when I run the above, I get this as a reponse:
#echo off
for /f "delims=" %%a in (
%%a was unexpected at this time
'sqlplus USER/PASS#OMP1 #VoiceBlockTrig.SQL'
''sqlplus' is not recognized as an internal or external command, operable program or batch file
) do set rowcount=%%a
if %ROWCOUNT% GTR 0 (
More? c:\SQLTRIGGERS\VoiceBlkAutoationBAT.bat
More?
when I run this:
sqlplus user/pass#P1 #VoiceBlockTrig.SQL
I do get an integer value back too
why is there such a gap between the SET and rowcount?
In itself, it's of no matter - but I suspect that you have them on separate lines.
The set rowcount=%%a must all be on the same physical line as the do - and the do must be on the same physical line as the closing parenthesis after the in
for /f "delims=" %%a in (
'sqlplus user/pass#P1 #VoiceBlockTrig.SQL'
) do set rowcount=%%a
if perfectly legitimate.
As a .bat file:
:: #echo off
echo starting SQLPLUS
sqlplus USER/PASS#OMP1 #VoiceBlockTrig.SQL
echo finished SQLPLUS
for /f "delims=" %%a in (
'sqlplus USER/PASS#OMP1 #VoiceBlockTrig.SQL'
) do ECHO(+%%a+&set /A rowcount=%%a
ECHO rowcount=+%rowcount%+
if %ROWCOUNT% GTR 0 (
c:\SQLTRIGGERS\VoiceBlkAutoationBAT.bat
)
PAUSE
This is the batch that appears to be close to what you'd need to run.
The changes are:
added ECHO(+%%a+ in the FOR loop.
The open-parenthesis following the ECHO is simply a character that has been found to be better than SPACE to separate the ECHO from the text-to-be-echoed
The + before and after the %%a simply delimits the string with an
obvious character so that the presence of SPACES can be more easily observed.
SET changed to SET /A which interprets the value assigned as a
numeric-string, which should overcome any stray spaces in the
assignment.
Added ECHO of the rowcount within delimiters for visibility
Added PAUSE to stop the procedure from closing before you have a chance to see the results.
Comment : Probably the "delims=" is not required, but we'll get to that when the problems are defeated.
Comment: Your report that the script required TWO ENTERs could mean that the SQLPLUS is asking for input. If so, 'ECHO.^|sqlplus... may alleviate the problem.
If SQLPLUS is a BATCH, a different approach would need to be made.
Further changes to attempt to solve puzzing result:
Double-colon before #echo off - double-colon is often used as a
comment. The object is to show the lines being executed.
Added the SQLPLUS command independently - to observe results.
Added two ECHO lines to display progress.
Certainly very odd....
Related
While running something like .bat, the "X:\..\..path" often becomes ""X:\..\path and producing errors. For example, I was installing apktool, then it just appeared this:
'""C:\Program' is not recognized as an internal or external command,
operable program or batch file.
I then copy the command and put one of the double quote to the end, which is like this: "C:\Program"
And everything just went smoothly, installation was successful. Then I tried to decode an apk, and the exactly same problem occurred: '""C:\Program' is not recognized as an internal or external command, operable program or batch file. This time I have no idea how to fix it, it's not like the .bat now, I cannot get the #echo on and copy the last command and edit it. So I am here to ask: If I am the only one who met this? Any way to fix this? Thank you.
My command:
apktool d test.apk
Image of running a decode command : 1
apktool.bat content:
#echo off
setlocal
set BASENAME=apktool_
chcp 65001 2>nul >nul
set java_exe=java.exe
if defined JAVA_HOME (
set java_exe="%JAVA_HOME%\bin\java.exe"
)
rem Find the highest version .jar available in the same directory as the script
setlocal EnableDelayedExpansion
pushd "%~dp0"
if exist apktool.jar (
set BASENAME=apktool
goto skipversioned
)
set max=0
for /f "tokens=1* delims=-_.0" %%A in ('dir /b /a-d %BASENAME%*.jar') do if %%~B gtr !max! set max=%%~nB
:skipversioned
popd
setlocal DisableDelayedExpansion
rem Find out if the commandline is a parameterless .jar or directory, for fast unpack/repack
if "%~1"=="" goto load
if not "%~2"=="" goto load
set ATTR=%~a1
if "%ATTR:~0,1%"=="d" (
rem Directory, rebuild
set fastCommand=b
)
if "%ATTR:~0,1%"=="-" if "%~x1"==".apk" (
rem APK file, unpack
set fastCommand=d
)
:load
"%java_exe%" -jar -Duser.language=en -Dfile.encoding=UTF8 "%~dp0%BASENAME%%max%.jar" %fastCommand% %*
rem Pause when ran non interactively
for /f "tokens=2" %%# in ("%cmdcmdline%") do if /i "%%#" equ "/c" pause
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.
set java_exe="%JAVA_HOME%\bin\java.exe"
Should be
set "java_exe=%JAVA_HOME%\bin\java.exe"
(apply this principle throughout your code)
Then, if you require " anywhere, insert it where it's needed - don't try to include it as part of a variable's value.
This should clean up at least some of your problems.
i know this was already discussed but i didn't find what i needed.
I need to add new lines at the end of the hosts window file but,
first i need to check if these lines already exist and than adding them.
I tried this:
set "list=examp.com=examp2.com=examp3.com"
SET NEWLINE=^0.0.0.0
for %%a in (%list%) do (
FINDSTR /I %%a %WINDIR%\system32\drivers\etc\hosts)
IF %ERRORLEVEL% NEQ 0 (ECHO %NEWLINE% %%a>>%WINDIR%\System32\drivers\etc\hosts)
pause
but the result in hosts is just 1 line like this:
0.0.0.0 %a
I also want to know if it's possible to change this:
set "list=examp.com=examp2.com=examp3.com"
with another code that will take variables from a txt file.
Your code is not quite as bad as Mofi would suggest. Although it's quite uncommon to use an equal sign as a delimiter for a for loop, it is nevertheless legal syntax. The largest two problems I see are that you're closing your for loop at the end of your findstr statement; and, assuming you fix that, %ERRORLEVEL% would need its expansion delayed. Or you could use the if errorlevel syntax of the if statement (see help if in a cmd console for full details`). Or even better, use conditional execution.
Here's an example using conditional execution. This example also opens your HOSTS file for appending one time, rather than one time for each loop iteration -- a subtle efficiency improvement, true, but a worthwhile habit to practice when writing files with a loop. And because HOSTS by default has attributes set to prevent writing, I stored and removed the read-only / system / hidden / etc. attributes of the hosts file, appended the changes to the file, then restored the attributes back the way they were before.
#echo off & setlocal
set "hosts=%WINDIR%\system32\drivers\etc\hosts"
set "list=examp.com=examp2.com=examp3.com"
SET "NEWLINE=0.0.0.0"
for /f "delims=" %%I in ('attrib "%hosts%"') do set "raw=%%~I"
setlocal enabledelayedexpansion
for /L %%I in (0,1,18) do if not "!raw:~%%I,1!"==" " set "attrs=!attrs!+!raw:~%%I,1! "
endlocal & set "attrs=%attrs%"
attrib -h -s -r -o -i -x -p -u "%hosts%"
>>"%hosts%" (
for %%a in (%list%) do (
>NUL 2>NUL find /I "%%a" "%hosts%" || echo(%NEWLINE% %%a
)
)
attrib %attrs% "%hosts%"
I'm trying to read the output of a command (which outputs into multiple lines), and use an arbitrary number of those lines. Because I know neither the number of total lines, nor the number of lines that will be used, I need to analyse and possibly use each line in a loop, which is why I have setlocal enabledelayedexpansion.
Below is a snippet of the code that shows the process of taking the command and reading each line (not using it yet, just reading it to make sure this works (which it doesn't)):
#echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%i in ('svn status') do (
echo %%i
set file=%%i
echo *!file!
)
The problem that I'm running into is that the %%i values that are being read in are not correct in the for line. The first character is missing from the first line of the input (which is important because I use the first line to decide whether or not to use that line).
The output I get from my code looks like this:
Dir0\TestDoc7.txt
? StatusFile.txt
Whereas if I run this code:
copy /y NUL StatusFile.txt >NUL
>StatusFile.txt (
svn status
)
(Which is just another way of me seeing what the real output of svn status is) I get a proper output into the text file:
! Dir0\TestDoc7.txt
? StatusFile.txt
I'm probably making a fairly clear mistake as I'm rather new to batch scripting.
Thanks in advance.
The cause is EnableDelayedExpansion which will eat the exclamation marks,
Your choice of tokens=* will also strip all leading spaces from the lines.
#echo off
for /f "tokens=1*" %%A in ('svn status') do (
if "%%A" equ "!" (
Rem do whatever
) else If "%%A" equ "?" (
Rem do something else rest of the line is in %%B
) else (
Rem no ! or ? first space sep. content is in %%A rest of the line is in %%B
)
)
I am searching for certain XML files and then performing a command on them (mvn) which writes an output to a tree.out file. If this file is empty then I know there was no output (from mvn), so I don't print it.
However, after the first part of the loop execution it prints out from set size and then simply prints out the commands of the next loop iterations.
setlocal enabledelayedexpansion
set pomFiles=dir /s/b pom.xml
#echo off
for /f %%f in ('%pomFiles%') do (
findstr "<packaging>pom</packaging>" %%f > nul
if errorlevel 0 if not errorlevel 1 (
cd "%%~dpf"
mvn -q dependency:tree -Dincludes^=%dependency% -DoutputFile^="%%~dpftree.out"
for /f %%i in ("%%~dpftree.out") do set size=%%~zi
if !size! gtr 0 (
type "%%~dpftree.out"
)
del "%%~dpftree.out"
)
)
I presume there is an error in my code which is causing the statements to print, but I cannot see what the issue is myself.
The syntax of for /f for files is
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
but in your code the file-set is ("%%~dpftree.out") which is for strings.
To use double quotes, I think you have to use the usebackq option:
for /f "usebackq" %%i in ('%%~dpftree.out') do set size=%%~zi
Hope this helps
The problem was that I was running the command
mvn -q dependency:tree -Dincludes^=%dependency% -DoutputFile^="%%~dpftree.out"
without using the key word call before it.
Using
call mvn -q dependency:tree -Dincludes^=%dependency% -DoutputFile^="%%~dpftree.out"
stopped the commands being printed.
I know this an old thread but I've spent hours looking for an answer which didn't worked for me and this being one of the most popular answers to this question, I'll post it here.
I've noticed that the sintax when ( or ) is being used, is really strict. So using an editor like Sublime, or Notepad++, I've found one space char just next to one ), in a 500 lines batch, that threw off the #echo off statement.
In other words( * being used to visually represent a space at the end of line):
IF %randomvar% EQU 1 (*
goto DO
) ELSE (
goto DOELSE
)**
Either * or **, will mess #echo off and will output every line of code to console.
Just make sure that you don't have any unnecesary chars at the end of lines.
Cheers
I need to check for certain processes (its a list of 20ish processes, so wont list them all), and record which ones are running. Then I need to kill them, run some other code, and finally reopen them... The code will only run successfully if all the processes have been ended.
I'd welcome any suggestions, or just someone to explain why my code doesn't work.
What I've been doing, is using tasklist to check for each process, and write the results to a file, then I'm trying to remove the lines of the file where the process is not running (i.e. I get an "INFO:..." message)
I know that I have done something similar before, where I've taken each line of a file one at a time (in a for loop), replaced a string of text within it, and sent the edited line to another file (which is probably not the most efficient way of doing it, but it worked).
For some reason, I can't replicate it now...
The code I've got (whch is failing) is
SETLOCAL ENABLEDELAYEDEXPANSION
cd\
for /f "tokens=* delims= " %%a in (somefile.txt) do (
set q=INFO: No tasks are running which match the specified criteria.
set r=%%a
set s=!r:%q%=!
echo %s% >>test.txt
)
If anyone knows of a better way to do what I need, I'm happy to change my plan, but it does need to be done through batch (CMD), or I'd be happy with some one fixing the above code at least.
Thanks
Try this code. Though I'm not sure if the output file matches the one you want. Make sure to surround the parameter with double quotes if it contains any space.
taskchk.cmd:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
if "%1" == "" (
echo Please specify criteria.
echo e.g.: taskchk myprocess.exe
goto :eof
)
cd\
type nul>test.txt
set found=0
for /f "tokens=*" %%a in ('tasklist /nh') do (
for /f "tokens=1" %%b in ("%%a") do (
if /i "%%b" == "%~1" (
set found=1
) else (
echo %%a>>test.txt
)
)
)
if %found% == 0 echo INFO: No tasks are running which match the specified criteria.>>test.txt