I tried many examples online, but was not able to make it work. I am new to this so please forgive my primitive question.
say I have this:
curl "www.google.com" -o /dev/null -s -w "%{http_code}\n"
when running this in a cmd window, it returns the response code.
200
which is as expected.
I would like to do something like this in a batch script, but also use the output of the curl command to set a variable.
All examples I found online propose:
set res = $(curl "www.google.com" -o /dev/null -s -w "%{http_code}\n")
echo %res%
pause
or like this
FOR /F "tokens=* USEBACKQ" %%F IN (`curl www.google.com -o /dev/null -s -w "%{http_code}\n"`) DO ( SET var=%%F )
ECHO %var%
pause
both did not work, my batch script closes immediately.
Any feedback or help is highly appreciated
thank you.
Thanks to #Compo, here is the formatted answer for other's benefit.
#echo off
For /F %%G In ('%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}\n"') Do Set "response=%%G"
echo response code is %response%
IF %response% == 200 (
ECHO was able to ping google
) ELSE (
ECHO unable to ping google
)
pause
As he has mentionned above #Compo in his comment :
"To get the result of the command as a variable at the Command Prompt, you'd use For /F"
#echo off
Title Store curl command output in a variable in batch script
Set "MyCommand=curl "www.google.com" -o NUL -s -w "%%{http_code}""
#for /f %%R in ('%MyCommand%') do ( Set VAR=%%R )
echo %VAR%
pause
Based upon your own answer code, there's no need to use a for-loop to get the result saved to a variable, and then compare that variable value with a known value. You can pipe the result through findstr to see if it matches your known value instead.
Example batch-file:
#%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}" ^
| %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded
) || Echo Ping Failed
#Pause
It is only really one line, split for readability, so you could do it line this in cmd:
%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%{http_code}" | %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded) || Echo Ping Failed
Or like this as a batch-file:
#(%__AppDir__%curl.exe -s -o NUL "www.google.com" -w "%%{http_code}" | %__AppDir__%findstr.exe /X "200" 1> NUL && (Echo Ping Succeeded) || Echo Ping Failed) & Pause
Other answers are good, but I would not use CURL to just test if we can reach a site:
#echo off
ping google.com -n 1 >nul 2>&1
if %errorlevel% equ 1 (
echo EHHH..NO Google is not down, we are
) else (
echo HURRAH MAN We are OK
)
Related
I am working on a batch file that calls 4 other batch files. If the sub-batch file returns with an errorlevel code other than 0, I want the parent batch file to capture it, send out an email and exit the parent batch file. However, as soon as the first child batch file is called and returns with a non-zero errorlevel, none of the subsequent commands in the parent batch file run. Here is my batch code:
rem ** setup so it logs itself **
set parent=%~dp0
set me=%~n0
set LOGFILE=%parent%logs\%me%.log 2>&1
if exist "%LOGFILE%" del %LOGFILE% /f /s /q
call :LOG > %LOGFILE%
exit
:LOG
#ECHO OFF
SETLOCAL ENABLEEXTENSIONS EnableDelayedExpansion
echo ParentDir: %parent%
echo ProgramName: %me%
echo.
rem ** script variables **
set batFile1=%parent%FILE1.bat
set batFile2=%parent%FILE2.bat
set batFile3=%parent%FILE3.bat
set batFile4=%parent%FILE4.bat
set FromEmail=server#domain.com
set Recipient=adminuser#domain.com
set CCRecipient=
set Subject=Email Subject
set Message=There was an error in running nightly batch files. Please look at the logs to determine which batch file is causing a problem. \n\nAt your service\nAdmin
set Server=smtp.domain.com
set Port=25
rem ** run bat files and capture error message **
echo.
echo Start: Send Email
set Message=Debug test code
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
call %batFile1%
set exitcode=%ERRORLEVEL%
echo %exitcode%
echo.
echo Start: Send Email
set Message=Debug test code !exitcode!
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
if %exitcode% NEQ 0 (
echo.
set Message=Execution of !batFile1! failed with error message !errorcode!. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f !FromEmail! -t !Recipient! -cc !CCRecipient! -u "!Subject!" -m "!Message!" -v -s !Server!
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile2%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile2% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile3%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile3% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile4%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile4% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
EXIT /B %ERRORLEVEL%
It appears that none of the lines of code are executed that follow the command call %batFile1%
For information purposes, this is how the %batFile1% exits:
EXIT /B 254
so that should be coming back with %ERRORLEVEL% 254 every time. the test email that I send just before calling batFile1 works fine.
#echo off
setlocal EnableExtensions
rem ** setup so it logs itself **
set "parent=%~dp0"
set "me=%~n0"
set "LOGFILE=%parent%logs\%me%.log"
if exist "%LOGFILE%" del "%LOGFILE%" /f /s /q
call :LOG > "%LOGFILE%" 2>&1
exit
:LOG
setlocal
echo ParentDir: %parent%
echo ProgramName: %me%
echo.
rem ** script variables **
set batFiles="%parent%FILE1.bat" "%parent%FILE2.bat" "%parent%FILE3.bat" "%parent%FILE4.bat"
set "FromEmail=server#domain.com"
set "Recipient=adminuser#domain.com"
set "CCRecipient="
set "Subject=Email Subject"
set Message=There was an error in running nightly batch files.^
Please look at the logs to determine which batch file is causing a problem.\n\n^
At your service\n^
Admin
set "Server=smtp.domain.com"
set "Port=25"
rem ** Send email test **
echo.
echo Start: Send Email
set Message=Debug test code
c:\APPS\sendemail.exe -f "%FromEmail%" -t "%Recipient%" -cc "%CCRecipient%" -u "%Subject%" -m "%Message%" -v -s "%Server%"
rem ** run bat files and capture error message **
for %%A in (%batFiles%) do (
call :EMAIL %%A
if errorlevel 1 exit /b
)
exit /b
:EMAIL
setlocal
echo.
call "%~1"
if errorlevel 1 (
echo %errorlevel%
set "exitcode=%errorlevel%"
) else exit /b
rem ** Send email **
if "%~n1" == "FILE1" (
set "Message=Debug test code %exitcode%"
) else set Message=Execution of '%~1' failed with error message %exitcode%.^
Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f "%FromEmail%" -t "%Recipient%" -cc "%CCRecipient%" -u "%Subject%" -m "%Message%" -v -s "%Server%"
rem ** force execution to quit if check fails **
if %errorlevel% neq 0 echo Email send error message %errorlevel%.
exit /b
With optimizing the code some, to remove duplication etc.
It appears to be working better. I may have accidently fixed it.
Suggest checking echo %errorlevel% of the call before using
set, else %errorlevel% is of the set command.
None of the new code requires delayed expansion, so remove the
EnableDelayedExpansion setting.
Scripts are set to one variable and is used as a file-set,
in a for loop.
Many of set variable=value are double quoted to avoid any
trailing space issues. Those not, are multiline etc. that
are better without.
The Send Email code is not in a label :EMAIL which helped
to merge the duplicate code. It does a check if name FILE1
is the argument and uses a different email message to match
your original code.
It will end the script if sendemail.exe sets %errorlevel%
to not zero, which is later checked in the for loop.
If you want to exit on the called child batch-file instead,
change the last line from exit /b to exit /b %exitcode%.
Note, implicit use of exit /b is same as exit /b %errorlevel%.
If you prefer the later, update the code to you preference.
The later may require delayed variable expansion if used
in a code block i.e. (command & exit /b !errorlevel!).
im trying to create a batch file that goes thorugh each text file in a folder and looks for specific words such as "msg" "file" "size" in each line. If those words are found then it sends and me an email.
Im using SQL server to send the email, and im calling the email stored procedure from my batch file like this:
set MYDB= yourDBname
set MYUSER=youruser
set MYPASSWORD=yourpassword
set MYSERVER=yourservername
sqlcmd -S %MYSERVER% -d %MYDB% -U %MYUSER% -P %MYPASSWORD% -h -1 -s "," -W -Q "exec yourstoredprocedure"
I just need help writing the script which checks for specific words in each line in each .txt file
Just give a try for this batch file :
#echo off
Title Search String into text files
Set "ROOT=%~dp0"
set "String2Search=msg size file"
For %%a in (%String2Search%) do (
FOR /f "delims=" %%f IN ('dir /b /s "%ROOT%\*.txt"') DO (
(find /I "%%a" "%%f" >nul 2>&1) && ( Call :FoundString "%%a" "%%f" ) || ( Call :NoFound "%%a" "%%f" )
)
)
pause & exit
::*************
:FoundString
echo found %1 on file %2
goto :eof
::*************
:NoFound
echo no string like %1 found on file %2
goto :eof
::*************
Few suggestions as i cannot comment.I had done a project few years back and i had to do search files with a particular extension and read them to find particular words and do something with them.I remember few things only.I hope it helps you.
To find all txt files:
find /home/user/Downloads/etc -name '*txt'
To read a whole file and search for "msg" "file" "size":
while read -r LINE
do
grep -i "msg" | grep -i "file" | grep -i "size"
to check all in one line
Or you can do it executing one by one without "pipelining".
P.S I don't have linux installed otherwise I would have checked before posting.Sorry if not correct.
This should do the job:
#ECHO OFF
CD C:\wherever\your\.txt\files\are\at
FOR /R %%G IN ("*.txt") DO (FINDSTR /I /C:"msg" /C:"file" /C:"size" "%%G" >nul && GOTO match_found)
GOTO no_match
:match_found
ECHO Match found^!
set MYDB= yourDBname
set MYUSER=youruser
set MYPASSWORD=yourpassword
set MYSERVER=yourservername
sqlcmd -S %MYSERVER% -d %MYDB% -U %MYUSER% -P %MYPASSWORD% -h -1 -s "," -W -Q "exec yourstoredprocedure"
:no_match
ECHO No match found^!
PAUSE
If the batch file is in the same folder as the .txt files you can delete the CD line.
If the search should be case-sensitive remove the /I option.
To satisfy your question as asked, this should suffice:
#Echo Off
FindStr /IR "\<msg\> \<file\> \<size\>" "C:\Users\NT-Hero\*.txt">Nul||Exit /B
Rem Your 'match found' commands here
If you wanted to also search in sub-directories change the FindStr options to /SIR. (See FindStr /? for more options).
I have a very simple batch file that runs a SQL query file and copies the results to a printer. The problem is it prints even if the results of the query is 0 rows. How can I only print if there is data?
cd stock
sqlcmd -i testquery.sql -S localhost -U User -P password -o testresults.txt
copy testresults.txt \\printserver\share
sqlcmd -i ems_update.sql -S localhost -U User -P password
del c:\stock\testresults.txt
exit
Ok, this is what I have now:
cd c:\stock
sqlcmd -i testquery.sql -S localhost -U User -P password -o testresults.txt
#find /c /i "0 rows" "C:\stock\testresults.txt" > NUL
if %ERRORLEVEL% EQU 1 (
pause
) else (
copy c:\stock\testresults.txt \\printserver\share)
pause
sqlcmd -i ems_update.sql -S localhost -U User -P password
I cannot get the copy command to run now. What am I missing??
thanks
Take a file that you know has 0 data.for /f "delims=" %%A in ('type nodata.txt') do set nodata=%%AThenfor /f "delims=" %%A in ('type testresults.txt') do set test_result=%%AThenif not %nodata%==%test_result% copy testresults.txt \printserver\shareThis will only work if the same exact no data file is produced, like no timestamps.or
use find which returns %errorlevel%==1 if it does not find a phrase in file and 0 if it does.
Just an idea - you can check if size of the file is 0. In Bash it would be something like this:
if [ ! -s ./testresults.txt ] ; then
rm ./testresults.txt
# or do something else
else
copy testresults.txt \\printserver\share
fi
I have a command that watches a certain folder for new files. These files are created by a video transcoder so are locked and keep growing in size till completion.
#echo OFF
:loop
if exist "E:\OUT\*.mxf" (
for %%i in ("E:\OUT\*.mxf") DO (
C:\bmx\bmxtranswrap -o "E:\DPP_create\DPP_OUT\%%~ni.mxf" -t as11op1a -y 09:59:50:00 --afd 10 "%%i"
ping -n 5 localhost >nul
del "%%i"
)
)
ping -n 5 localhost >nul
goto :loop
Is there a way to only pick up files which are fully completed (Windows unlocked)? At the moment the next command is tripping up as it is attempting to open an incomplete file.
Any advise? Thanks.
As long as you are correct in that your transcoder has the file locked until it is complete, then the solution is actually simple.
Use redirection to test that you can open the file for writing, but don't modify it. Only process if the redirection succeeded.
Note:
You don't need your outer IF statement.
You can use an infinite FOR /L loop instead of a GOTO loop
I don't understand why you need a delay before your DEL, but I preserved it anyway.
#echo OFF
for /l %. in () do (
for %%i in ("E:\OUT\*.mxf") do 2>nul( (call )>>"%%i" ) && (
C:\bmx\bmxtranswrap -o "E:\DPP_create\DPP_OUT\%%~ni.mxf" -t as11op1a -y 09:59:50:00 --afd 10 "%%i"
ping -n 5 localhost >nul
del "%%i"
)
ping -n 5 localhost >nul
)
I will be muxing 100's of (.mkv)'s via mkvmerge command line (.bat) file and would like to know if it's possible to have all occurrences of the words warning and error highlighted in yellow(warning) and red(error) and or change the text color.
I tried this "Setting Text Color in a Batch File" but the outcome is not specific to what I'm trying to accomplish.
My batch as it is:
#echo off
cls
md output
for %%a in (*.mkv) do (
"mkvmerge" --track-name -1:"" --no-attachments --no-track-tags --no-global-tags --disable-track-statistics-tags --display-dimensions "0:1280x720" --language -1:eng --default-track -1:yes --compression -1:none --no-chapters -o output/"%%~na.mkv" -a 1 -d 0 -S "%%~na.mkv" --track-order 0:0,0:1 --language 0:eng --stracks 0 "%%~na.idx"
)
This gave me the results I was looking for...
MTEE Mtee commandline utility
#echo off
md output
md results
for %%a in (*.mkv) do (
"mkvmerge" --track-name -1:"" --no-attachments --no-track-tags --no-global-tags --disable-track-statistics-tags --display-dimensions "0:1280x720" --language -1:eng --default-track -1:yes --compression -1:none --no-chapters -o output/"%%~na.mkv" -a 1 -d 0 -S "%%~na.mkv" --track-order 0:0,0:1 --language 0:eng --stracks 0 "%%~na.idx" 2>&1 | mtee/+ results\"%%~na.txt"
)
cls
findstr /a:04 Error "results\*.txt"
findstr /a:0E Warning "results\*.txt"
echo.
powershell -c (New-Object Media.SoundPlayer "C:\Windows\Media\notify.wav").PlaySync();
echo The process is complete.
pause
exit