Batch file set command issue - batch-file

Have created a batch script and found that the values are not getting set when trying to read from for loop.
sqlplus #D:\Batch_job\Sql\COUNT.sql>D:\Batch_job\COUNT.txt
FIND /C /I "ORA-" D:\Batch_job\COUNT.txt >D:\Batch_job\ERR.txt
FOR /F "tokens=3" %%B IN (D:\Batch_job\ERR.txt) DO SET COUNT_ERROR=%%B
ECHO %COUNT_ERROR%
The above echo is not returning any value. I tried using enabledelayedexpansion, too. But that is also not working. When I tried to create some test script and execute just this much chunk than it is giving me result. But when called from the whole script the result is always same NULL.

Related

Removing one ShadowCopy with a batch file

I'm working on modifying a batch file used for backups. When it runs it creates a new shadowcopy, mounts it, backups what it should, and dismounts it. What I would like to do is have it delete the shadowcopy it created. I don't what to delete existing shadowcopys for forensic reasons. Here is the section of code I'm having and issue with.
:DeleteNewSCopy
REM : Locates then removes the last created shadowcopy.
SET ShadowID=
FOR /F "usebackq tokens=1,2* delims=:" %%A IN (`FINDSTR /I /C:"Shadow Copy ID:" %TempFile%`) DO SET ShadowID=%%B
IF NOT "%ShadowID%" == "" (
REM : Last ShadowCopy ID was found, Nuke it.
vssadmin delete shadows /Shadow=%ShadowID%
) ELSE (
ECHO No ShadowCopy ID found.
)
GOTO :EOF
The FOR line seems to be working correctly. When I ECHO out the %ShadowID% during run-time I get:
ShadowID: {4fcb026a-08fe-4a34-b198-da7560db57bf}
But the line to delete the shadowcopy fails with:
Error: Invalid option value.
In the command line I can set ShadowID to have the same string and run the command without issue, so I seems like it should work in the batch file.
Any assistance will be appreciated.
I found that the problem wasn't with the code it was with how I was pulling the variable ShadowID. It had a leading space that needed to be removed. I used a solution posted by Foumpie to get it fixed.
https://stackoverflow.com/a/12089079/8272143

How to set a variable in a FOR loop that is involved in a pipe?

I know this question has been ask many times, but I've read the answers for hours and tried everything, nothing seems to work. Basically I can't succeed to (Re-)SET a variable in a for /F loop.
I would like to do the following : check the connection between two computers and do an action (basically start a program) if the connection doesn't exist anymore.
#ECHO OFF
SET _A=0
PING localhost | (for /F "tokens=*" %%a in ('FINDSTR Reply') DO #ECHO %%a & SET _A=1)
if %_A%==0 ECHO %_A% FAIL
if %_A%==1 ECHO %_A% SUCCESS
PAUSE
Here I assume that if the PING command doesn't return at least once the word "Reply", then the connection was lost.
The first "DO #ECHO %%a" works, but then it doesn't reset the variable "_A". And I need this variable to be external to the FOR loop because after that the "if %_A%==1" will have to execute the program only once.
Anyone knows what I'm doing wrong ? Thanks a lot for your help. I really tried everything, included setlocal enabledelayedexpansion and putting variable between !!, but nothing works, it always ends up printing "FAIL" and never "SUCCESS".
This is a great question! The problem is the pipe | as this initialises separate termporary cmd instances for both sides. The variable _A is set in the right instance but is lost afterwards.
If you do:
for /F "tokens=*" %%a in ('PING localhost ^| FINDSTR Reply') do #ECHO %%a & SET _A=1
it will work as the set command is in the main cmd instance the batch script is running in.
Note the escaped pipe ^|, which is necessary to transfer its execution to the cmd instance created by for /F for the command line it parses.

How to tell a batch script where another script is?

I have a script that I can run in the command line to get me the version of software. It works perfectly in the command line. I type this in getversion "<full path>" and it gets me exactly what I need.
Now the catch is that I have to have the getversion.bat and a vbscript file both in the directory that I'm in for the command line. This is probably a dumb question but if I want to add this into a batch script where the version is set as a variable how would I do that?
right now I had it looking like this
#echo off
set version=getversion "<full path>"
echo %version%
pause>nul
The problem seems to be that the batch file doesn't know where to find getversion.bat or the vbscript referenced in that script. How can I tell the batch file where they are?
One way to accomplish this is to direct the output of your function to a file and then read this output back into a local variable using a SET /P command. This should do it:
SET TempFile="%Temp%\%RANDOM%.txt"
REM Direct output to a temp file.
CALL getversion "<full path>">%TempFile%
REM Read the output written to the temp file into a local variable.
SET /P Version=<%TempFile%
ECHO %Version%
REM Cleanup.
IF EXIST %TempFile% DEL %TempFile%
Alternately (and this way much "cleaner"), you can use a FOR command to run your function and store the output into a local variable:
FOR /F "usebackq tokens=* delims=" %%A IN (`CALL getversion "<full path>"`) DO SET Version=%%A
ECHO %Version%

How to put a single PowerShell output string into a cmd variable?

I have a PowerShell script that outputs a single string value. I have a cmd batch script that needs to execute the PowerShell script and place that single PowerShell output value into a variable in the batch script. I'm finding all sorts of methods for exporting to a file or reading a file but that's not what I want. Thanks!
(edit) Here's where I'm trying to use it (in response to posting the script):
#echo off
REM The next line puts the .ps1 output into the variable
REM and, obviously, this does not work
set pass_word=<C:\temp\PullPassword.ps1
tabcmd login -s "http://myserver.net" -u mylogon -p %pass_word%
( edit )
I saw the answer by the OP here Getting Powershell variable value in batch script and also looked at foxdrive's answer so I started playing with the FOR...DO statement. I thought I was pretty good with cmd and couldn't figure out why what I had wasn't working:
for /f "delims=" %%a in ('powershell . "C:\temp\PullPassword.ps1"') do set val=%%a
echo %a%
When I was looking at foxdrive's full answer in the other post it struck me: %a% was wrong, I needed %val%! Oh, the shame! The below works:
#echo off
set mypath=C:\temp\PullPassword.ps1
for /f "delims=" %%a in ('powershell . "C:\temp\PullPassword.ps1"') do set pass_word=%%a
tabcmd login -s "http://myserver.net" -u mylogon -p %pass_word%
So I'll credit where it's due and mark foxdrive's answer correct, even though it was the other post that clarified my mistake.
This may help: it expects that the powershell script outputs the text to STDOUT which is the normal place for it to appear.
#echo off
for /f "delims=" %%a in (' powershell "script.ps1" ') do set "var=%%a"

Windows command prompt hangs for indefinite time

I have a script that performs upgrade to a database.
The script also logs before the upgrade starts, but when this script tries to access the log file it hangs for an indefinte time.
The line that's causing the issue is:
%LOGMESSAGE% Start update %UPDVERSION% .
LOGMESSAGE is a cmd file which is as follow:
SETLOCAL enabledelayedexpansion
SET /A FT=500
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year
/Format:table') DO (
IF NOT !FT!==500 GOTO proceed
SET FD=%%F-%%D-%%A
SET FT=%%B:%%C:%%E
:proceed
SET /A FX="DS"
)
endlocal
The main function of the LOGMESSAGE is to get the current system time.
The log file into which the scripts writes to has no issues and so does the function LOGMESSAGE, as the log file is written many times before the line %LOGMESSAGE% Start update %UPDVERSION% . is called. The script seems to work without any hassle on many other computer, but I am having an issue with one server, the server is running windows server 2003 R2 SP2.
Any idea what the issue might be?
try this:
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
SET /A FT=500
FOR /F "tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table^|find "20"') DO (
IF NOT !FT!==500 GOTO proceed
SET FD=%%F-%%D-%%A
SET FT=%%B:%%C:%%E
:proceed
SET /A FX="DS"
)
endlocal
If you just want to get the date and time, you can use
DATE /T
TIME /T
instead of WMI.
Three comments:
.cmd files are rare - normally, .bat files are used. There are minor differences between the two, but I'm not sure whether they would be relevant (I can no longer remember them...)
It's perfectly legitimate to have have a line-break just before the opening single-quote and just after the closing. A break in the middle of the command, I'm not sure about - not saying this IS a problem, but it's so easily eliminated.
I'm no longer sure, since I rarely use XP any more, and never S2003 - but ISTR there were problems with having a label within a block statement. The label seemed to end the block.
So - I'd suggest
running the routine as a .bat instead of a .cmd, using
for...(
'whatever whatever...'
) do (
structure, and implementing whatever tomfoolery is happening about FD, FT and FX within a subroutine.

Resources